- @property:编译器指令,在Xcode4.4之前,可以使用@property来代替getter/setter方法的声明,也就是说我们只需要写上@property就不用写getter,setter的声明,Xcode之后增强
@property int age;
- @syntheszie:编译器指令,可以简化getter/setter方法的实现
- 在@sythesize后面告诉编译器,需要实现哪property生成的声明
- 告诉@sythesize,需要将传入的值赋值给谁和返回谁的值给调用者
- 如果再@sythesize后面没有告诉系统将传入的值赋值给谁,系统默认会赋值给和@sythesize后面写的名称相同的成员变量
@syntheszie age = _age
- 从Xcode4.4之后,对@property进行了一个增强,以后只需要一个@property就可以同时生成setter/getter的声明和实现,如果没有告诉@property要将传入的参数赋值给谁,默认会将传入的属性赋值给——开头的成员变量
- 弊端:只会生成最简单的getter、setterd声明和实现,不会对数据进行过滤,必须自己重写
- 如果重写了setter方法,那么property就只会生成getter方法
- 如果重写了getter方法,那么property就只会生成setter方法
- 如果利用property来生成getter/setter方法,那么我们可以不屑成员变量,系统会自动给我们生成一个_开头的成员变量,是私有的成员变量(在.m生成的)
- 如果同时重写了getter/setter方法,那么property就不会自动帮我们生成私有的成员变量
- property修饰符
- 如果给一个属性同时提供了getter/setter方法,那么我们称这个属性为可读可写属性 readwrite(默认)
- 如果只提供了getter方法,那么我们称这个属性为只读属性 readonly
- 如果只提供了setter方法,那么我们称这个属性为只写属性 没有修饰符
- 如果既没有提供setter也没有提供getter方法,那么我们称这个属性为私有属性
@property(readonly) NSString *name;
@property(readwrite) NSString *name;
@property(getter=abc) NSString *name; 重新命名getter方法名称,用的多
@property(setter=abc) NSString *name; 重新命名setter方法名称
- id:动态数据类型,编译时并不知道真实类型,只有在运行时才会知道其数据类型,如果访问了不属于动态类型的属性和方法,编译器不会报错
- 定义变量
- 作为函数的参数
- 作为函数的返回值
- 弊端:由于动态类型可以调用任意方法,所以有可能调用到不属于自己的方法,而编译时又不会报错,所以可能运行时出错
- 一般用在多态,可以减少代码量,比卖你调用子类特有的方法需要强制类型转换
- 默认情况下所有的数据类型都是静态数据类型,在编译时就知道变量的类型,属性方法,在编译时就可以访问这些属性方法,并且如果访问了不属于静态数据类型的方法和属性时,编译就会出错
- id== NSObject * 万能指针,区别:id是动态数据类型,NSObject *是静态数据类型
- 通过静态数据类型自定义对象,不能调用子类特有方法
- 通过动态数据类型定义的变量,可以调用子类特有的方法
- 通过动态数据类型定义的变量,可以调用私有的方法
- 为了避免动态数据类型引发的运行时错误,一般情况下如果使用动态数据类型定义一个变量,在调用这个变量的方法之前会进行一次判断吗避免错误
id obj = [Person new]
if([obj isKindOfClass:[Person class]]){
}
- isKindOfClass :判断指定的对象是某一个类,或者某一个类的子类
- isMemberOfClass:判断指定的对象是否时当前指定类的实例
- isSubclassOfClass:判断一个类是不是一个类的子类
- new做了三件事情
- 1.开辟存储空间 +alloc方法
- 初始化所有的属性(成员变量) -init方法(默认情况下什么都没做)
- 返回对象的地址
- alloc做的事情
- 开辟存储空间,堆空间,并将isa指针指向类对象
- 将所有属性设置为0
- 返回当前实例对象的地址
- init方法(构造方法):默认情况下init的实现什么都没有做,返回初始化后的实例对象的地址,该地址和alloc返回地址时一样的
[[Person alloc] init] === [Person new]
- 在OC中以init开头的方法,就是构造方法。构造方法的用途:用于初始化一个对象,让某个对象以创建出来就拥有某些属性和值,重写init方法必须按照格式写
1.必须先初始化父类,在出说子类
2.必须判断父类是否初始化完成成功,只有父类初始化成功才能继续初始化子类
3.返回当前对象的地址
- (instancetype) init {
self = [super inti];
if(self){
}
return self;
}
- instancetype == id == 万能指针
- 如果init方法的返回值是instancetype,那么将返回值赋值给一个其他的对象会报一个警告(最开始如果返回类型是id的话,是不会报错的,但是现在会)
- id可以用来定义变量,可以作为返回值,也可以作为形参
- instancetype只能作为返回值
- id在百衲衣是不能判断对象的真实类型
- instancetype在编译时会判断对象的真实类型(把运行时的错误在编译时就能发现)
- 自定义构造方法--自定义init方法,W一定要大写,属性名称,方法不要以new开头
- 一定是对象方法
- 一定返回id/instancetype
- 方法名称一定以init开头
- (instancetype) initWithAge:(int) age {
self = [super inti];
if(self){
_age= age;
}
return self;
}
