OC由浅入深系列 之 属性

一、什么是属性

在OC中,用@property 关键字修饰的类的成员成为属性。

在属性出现之前,声名一个实例变量通常是这样的,以‘价格’为例:

在.h中如下声名:

@interface Product : NSObject {

    //声名实例变量

    float _price;

}

//声名getter方法
- (float)price;

//声名setter方法
- (void)setPrice:(float)price;

@end

在.m中实现:

- (float)price {

    return _price;

}

- (void)setPrice:(float)price {

    _price = price;

}

一般每一个属性都要执行三步操作:声名实例变量、声名getter,setter方法,实现getter,setter方法,而这些操作都是有固定格式的。既然有固定格式,那么就可以通过机器来完成,于是有了属性:@property。属性的作用就是代替以上繁琐的步骤,功能还是和上面还是一样的。

所以:属性就是为了简化编译前代码量,编译之后效果是一样的。

二、编译过程中,发生了什么?

1、在ivar_list中增加一个实例变量;
2、在method_list中增加getter,setter方法的描述;
3、在porp_list中增加一条属性的描述,计算该属性在对象中的偏移量;
4、给出getter,setter方法的实现;在setter方法中,从属性的偏移量开始赋值,在getter中,从属性的偏移量开始取值,为了取到正确的字节数,针对属性的指针做了强制类型转换。

三、属性的修饰符

1、在ARC下,属性有默认的修饰符:
-基本数据类型:atomic,readwrite,assign
-对象类型:atomic,readwrite,strong
2、 常用的修饰符及含义:

属性的属性.png

关于weak的实现,参照:http://www.cocoachina.com/ios/20171213/21520.html

四、面试考点:

1、NSString为什么要用copy关键字,如果用strong会有什么问题?

答:为了避免面向对象编程多态特性引起的错误。例如:如果用strong的话,NSString指针p1指向了NSMutbaleString对象p2(父类指针指向指向子类对象),此时如果p2针修改了这个值,那么p1的值也会改变,这就与NSString不可变字符串产生了矛盾,容易造成未知崩溃。不止是NSString,NSArray,NSDicionary也可能存在这样的问题。copy的话,会使p2拷贝出一个NSString类型的副本对象,即使修改了p2的值,也不会影响到p1,保证了程序的安全。

2、atomic能保证线程的安全吗?

答:不能,atomic是保证实例变量访问的原子性,也就是说getter,setter方法是线程安全的,但是不代表整个对象是线程安全的。比如,循环打印一个对象的属性1万次,然后直接调用对象的relase方法,就会导致崩溃。

3、@dynamic和@sythesize的作用是什么?

答:dynamic :直接或者动态的生成getter,setter方法,synthesize是将getter,setter方法与实例变量关联

4、copy修饰的属性对可变对象和不可变对象的处理方式相同吗?

答:不同;对于不可变对象比如NSString 直接指针指向该对象即可,对可变对象,调拷贝一份副本。

5、weak和assign的区别是什么?

答:weak修饰的属性会在对象释放后自动置为nil,原理是weak表(以对象地址为key,指向该对象的指针为value的hash表);assign修饰的属性在对象释放之后不会置为nil,在MRC下,经常会出现 [self.xxx relase];self.xxx = nil;的组合写法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容