属性修饰符
访问权限
-
readonly 只读权限
-
readwrite 可读可写权限
线程安全
-
atomic 原子性 注:atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的
@property (atomic,strong) NSString *testa;//正确
@property (noatomic,strong) NSString *testa;//错误
//atomic 保证setter getter 安全
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (NSInteger i = 0; i<10000000; i++) {
dispatch_async(queue, ^{
@autoreleasepool {
self.testa = [NSString stringWithFormat:@"testssss%zd",i];
NSLog(@"%@",self.testa);
}
});
}
});
//但保证不了对self.testa 进行其他操作的安全性
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (NSInteger i = 0; i<10000000; i++) {
dispatch_async(queue, ^{
if (i%2==0) {
self.testa = @"aaaaaaaaaaaa";
} else {
self.testa = @"aaaaa";
}
});
}
});
dispatch_async(queue, ^{
NSString *str = [self.testa substringWithRange:NSMakeRange(0, 7)];
});
-
nonatomic 非原子性 读写速度比atomic快,原因是不涉及线程安全的判断以及对应的操作
指定方法名称
-
getter=method 指定get方法名
-
setter=method 指定set方法名
内存管理
-
retain 一般是在MRC下用来修饰对象,修饰对象为强引用,使其引用计数+1,保证对象不被销毁,只要还有一个变量指向对象.对象就会保持在内存中.当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放.
-
assign 一般用来修饰基本数据类型,修饰对象为弱引用,而且不会将已经释放的指针值nil,容易引起野指针问题,在 set 方法中 ARC 系统不会调用 引用计数器相关的代码执行, 只是简单的赋值而已,计数器不会改变.其为非OC对象.
-
strong 和retain 但是,是在ARC下修饰对象的.在 set 方法中 ARC 系统会自动帮我们加入对 新值 retain 使其引用计数器 + 1 的代码,并且对旧 值进行 release 使其引用计数器 - 1 的代码.
-
weak 同样是出现在ARC下修饰对象的,修饰对象为弱引用,在 set 方法中 ARC 系统不会调用 引用计数器相关的 代码执行,只是简单的赋值而已,所以其引用计数器不会改变.其为OC对象。用weak修饰对象时安全的,因为用weak修饰过的对象,在对象被释放时,会将指向对象的指针置nil,避免了野指针的问题.
补充: weak置nil 是怎么实现的?
weak属性的特点:
weak 表明该属性定义了一种“非拥有关系” (nonowning relationship)。
为weak属性设置新值时,设置方法既不保留新值,也不释放旧值。
同assign类似,然而在属性所指的对象释放时候,属性值也会清空(nil out)。
runtime是如何实现 weak 变量的自动置nil?
weak 对象会放入一个 hash 表中。
用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc。
假如 weak 指向的对象内存地址是addr,那么就会以addr为键, 在这个 weak 表中搜索,找到所有以addr为键的 weak 对象,从而设置为 nil。
具体机制:
objc_storeWeak(&weakPo, Model)函数:
objc_storeWeak函数把赋值对象(Model)的内存地址作为键值key,将weak修饰的属性变量(weakPo)的内存地址(& weakPo)作为value,注册到 weak 表中。
如果Model为0(nil),那么把变量(weakPo)的内存地址(& weakPo)从weak表中删除,
可以把objc_storeWeak(&weakPo, Model)理解为:objc_storeWeak(value, key),并且当key变nil,将value置nil。
在Model非nil时,weakPo和Model指向同一个内存地址,在Model变nil时,weakPo变nil。此时向weakPo发送消息不会崩溃:在Objective-C中向nil发送消息是安全的。
-
copy 拷贝了一份相同的内容,在 set 方法中 ARC 系统会自动帮我们加入对 新值 copy 的代码。引用计数器不变.
未完待续...