1. 创建对象
[类名 new] : 堆内存中开辟存储空间,初始化isa指针和所有属性,返回指针地址。
创建对象时返回的地址就是类的第0个属性的地址。但类的第0个属性不是开发者写的,而是isa指针(占8个字节)。
类对象:程序加载时系统创建,存储类中所有methods.
实例对象:手动通过new创建,存储isa指针和属性。isa指针指向类对象。
注意点:
成员变量 : 不能在定义的时候初始化, 存放在堆空间,不会自动释放
全局变量:静态区,程序结束自动释放
局部变量:栈,自动释放
2. NSLog
%@用于输出对象
3. NSString
[str length] 字符串的个数,不是字节数。比如“中国”返回2
4.
typedef struct{
int year;
int month;
}Date;
stu->birthday = (Date){2000,3,23};
5.
#pragma mark -
#pragma mark - 注释
6. 快捷键
.m 和 .h切换 : commond + control + 箭头
7. 匿名对象
对象只使用一次的时候
8. 模板
Contents->developer->library-xcode->template
9. 点击类名+alt 查看类信息
单击类名, 查看右边? 选项显示的类信息
查询API
10. 封装
隐藏实现细节,对外提供公共接口。防止外界随意更改属性为不在约束范围内的值,而对外接口方法中可做判断防止非法操作
11. 成员变量最好用_开头,这样在setter方法中就可以这样:_size=size
13. 自定义代码块
14. 点语法
编译器会自动转换为getter或setter方法。
15. self关键字
self既可以调用类方法,也可以调用对象方法。谁调用了self所在的方法,那么self就表示谁
16. 继承
解决代码重复问题/继承使多态成为可能/耦合性强(父类不在了,子类也就不行了)
如果A继承了B,那么B将拥有A所有的属性和方法
17. 重写
对象方法和类方法可以重写,但是属性不可以
18. 成员变量可以在@implementation中定义,其他类中无法查看(@interface中private修饰的其他类中代码提示可以看到)
,无法访问,只能本类访问
19. 没有方法声明,只有方法实现,则该方法是私有方法。但OC中没有绝对的私有方法。
Person *p = [Person new]; id p1 = [Person new]; [p test]; //正确运行 [p1 test]; //正确运行 [p performSelector:@selector(test)]; //正确运行 [p performSelector:@selector(test) withObject:nil afterDelay:2.0]; //2秒后正确运行
20. 编译器指令@property: 不用写getter/setter的声明了。此时成员变量不要用_
@interface
{ int age}
@Property age;
@end
21. 编译器指令@synthesize : 不用写getter/setter的实现了
@implementation
@synthesize age = _age
@end
@synthesize age=_number 相当于 setAge:{ _number=age}
@synthesize age 相当于 把值赋给了age, 而不是_age
22. xcode4.4以后对@property做了增强,实现了setter和getter。 默认把值赋给了_age, 而不是age
如果重写了getter, 则@property只生成setter
实际上此时不用写成员变量, 会自动生成带_的私有成员变量,在.m中生成,不是.h
如果同时重写了getter,setter, 那么@property就不帮我们生成成员变量了
23. id 动态数据类型 : 编译器不知道变量的真实类型,运行时才能确定。若访问了不属于动态类型的属性和方法,编译器不会报错
id == NSObject * 万能指针,但NSObject *是静态类型
动态数据类型可以调用私有方法
静态数据类型: 编译的时候就已经知道是什么类型
Person *p = [Student new];
Person中没有eat方法,Student中有。[p eat]编译器会报错
可用isKindOfClass:判断类型以避免运行时错误 : 是某个类或某个类的子类
isMemberOfClass : 是某个类
NSLog(@"%d", [p isMemberOfClass:[NSObject class]]); //0 NSLog(@"%d", [p isKindOfClass:[NSObject class]]); //1
24. [Person new] == [[Person alloc]init]
alloc : 开辟存储空间,将所有属性置为0,返回地址
init : 没做什么的,但是不可缺
25. init开头的方法,构造方法,让某个对象一创建出来就拥有某些属性和值
- (instancetype)init
{ self = [super init];
if(self != nil){
//初始化代码
}
return self;
}
26. 重写- (NSString*)description;
27. id : 编译时不知道真是类型,可做变量,返回值,形参
instancetype编译时知道真实类型,只可做返回值
28. 自定义构造方法: initWithAge:
29. 属性名称和方法名不要以new开头,可能引发未知错误
30. 类工厂方法: 快速创建对象的类方法
类工厂方法中创建对象请用self, 这样子类调用时不会出错:
+(instancetype)personWithAge:{ Person *p = [self alloc] initWith...]]}
31. 类的本质及存储细节
32. 获取类对象
[实例对象 class]
[类名 class]
一个类在内存中只有一份类对象
-(void)demo:(Class p){
[[p alloc]init];
}
33. 程序一启动就会将类的代码加载到内存中,放到代码区。在这过程会调用+(void)load方法,只会调用一次
类第一次被使用的时候会调用+(void)initialize方法,只会调用一次
调用顺序:
父类 load
子类load
父类initialize
子类initialize