1.@property
一种更加便捷的构造成员的方式
- Object-C的属性通过@property自动生成getter和setter方法
- 在OC当中setter方法和getter方法都可以通过点语法快速访问
- 自动生成 “ _” + “变量名” 的实例变量
- 注意重写setter和getter方法,小心递归调用自身
- 重写setter不要使用self.进行赋值
- 重写getter不要使用用self.访问属性值
attribute的写法
@interface Person : NSObject
{
NSString *_name;
NSUInteger _age;
}
//自己声明
- (void)setName:(NSString*)name;
- (NSString*)name;
- (void)setAge:(NSUInteger)age;
- (NSUInteger)age;
@end
@implementation Person
//自己实现
- (void)setName:(NSString*)name {
_name = [name copy];
}
- (NSString*)name {
return _name;
}
- (void)setAge:(NSUInteger)age {
_age = age;
}
- (NSUInteger)age {
return _age;
}
@end
property的写法
@interface Person : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) NSUInteger age;
@end
@implementation Person
//有需要可以重写setter 或者 getter方法
- (void)setName:(NSString*)name {
_name = [name copy];
}
- (NSString*)name {
return _name;
}
@end
2.property修饰符
线程安全
-
atomic
原子性,默认,使用线程保护技术,消耗系统资源,生成自旋锁,多个线程同一时间只能有一个线程对其进行访问。- 原子性指的是一个操作不会被CPU中途叫停,然后再调度,不会被中断,要么执行完,要么不执行。
- 自旋锁在上一个线程没有执行完毕的时候,下一个线程会一直等待,不会睡眠,上一个线程执行完毕,下一个线程立刻执行。而互斥锁在等待的时候会进入睡眠状态,在上一个线程执行完毕之后,会被唤醒,然后再执行
- atomic需要耗费大量的资源,执行效率低
- atomic并不保证线程安全,它只会保证set内部安全,在外部不能保证安全
-
nonatomic
非原子性,没有多线程同时访问的情况下时使用
访问权限
-
readwrite
默认,同时生成getter与setter的方法,可读可写 -
readonly
只读,只会生成getteer方法 内存管理
-
assign
适用一些标量类型(int、long、char、float、double、Integer、CGFloat、Bool)
-
strong
强引用,只有OC当中的对象才能用到该属性,它使对象的引用计数加1。
-
weak
弱引用,只是进行引用,没有声明对该对象的拥有权,不会增加引用计数。
-
copy
-
常见比较
-
strong和retain
- 相同点:都是对对象进行内存管理,修饰基本数据类型会保存,都会增加对象的引用计数,set时先release掉旧的对象,将新的对象赋值给属性并进行一次retain
- 不同点:strong用于ARC,retain用于MRC
-
assgin和weak
- 相同点:都不会增加引用计数
- 不同点:assign可以修饰基本数据类型,也可以修饰OC对象,指向OC对象后,如果指向的对象被释放,需要手动置为nil;weak只能修饰OC对象,如果指向的对象消失后,自动置为nil,不会产生野指针。
-
strong与copy
- 浅拷贝:指针拷贝,不会产生新的对象,源对象的引用计数加1,多了一个使用该内存的指针,公用一块内存
- 深拷贝:对象拷贝,内容拷贝,会产生新的对象,源对象的引用计数不变;两个内存是不同的空间,两个指针指向不同的内存,互不干涉 NSObject提供了copy和mutableCopy两种拷贝方式
- 如果源对象也是NS* 类型,副本对象采用copy方法进行拷贝是浅拷贝,采用mutableCopy进行拷贝是深拷贝
- 如果源对象是NSMutable* 类型,副本对象采用copy或者mutableCopy都会进行深拷贝
对于strong和copy修饰的property
- 相同点:对于不可变对象都是浅拷贝
- 不同点: strong修饰的属性对于可变对象依然进行浅拷贝; copy修饰的属性对于可变对象是用深拷贝
-
3.最佳实践
- 基本类型用assign
- delegate用weak
- NSArray,NSDictionary和NSString,blcok用copy
- 其他用strong
- 避免出现环 A->strong -> B - strong -> C - strong -> A
为什么block要用copy
- block内部没有调用外部变量时存放在全局区(ARC和MRC下均是),这个时候不会有什么问题
- block使用了外部局部变量,MRC时block存放到栈上,栈区创建的对象在作用域外会被销毁,销毁后再调用可能会造成程序崩溃,使用copy之后block放在堆区,所以使用copy。在ARC当中的block都会在堆上,系统默认对block进行copy操作,将栈区的对象赋给strong修饰的属性默认也会copy,使用copy表明一致