使用线程安全的代码
1:原子属性
原子属性是现实应用状态安全的一个良好的开始,如果一个属性是atomic,则修改和读取肯定都是原子。
这个一点很重要,因为这样可以阻止俩个线程同时更新一个值,反之则有可能导致错误的状态,正在修改属性的线程必须处理完毕后,其他线程才可以进行处理,所有的属性默认都是原子性的,作为实践,在需要时应该显示的使用atomic,否则使用nonatiomic标记属性。
@Property (atomic) nesting *firstName; 原子
@Property (nonatiomic) nesting *department; 非原子
因为原子属性存在开销,所以过度使用它们是错误的,例如,如果能够保证这个属性在任何情况下都不会被多线程访问,那最好还是将标记nonatiomic。
@Property (nonatiomic,readwite,strong)IBOutlet UILabel *nameLabel; @Property (atiomic,readwite,strong)IBOutlet UILabel *nameLabel;
因为UIKit只允许在主线程操作UI元素,由于只会在指定的线程内访问,除了带来很大的开销,没有任何价值,所以用nonatiomic。
2:同步块的演示证明原子的不安全性
首先属性都是原子定义的
@Property (atomic) nesting *firstName; 原子
@Property (atomic) nesting *lastName; 原子
- (void)update:(User*)user strName:(NSString*)strName strTitle:(NSString*)title
{
user.name = strName;
user.title = title;
}
如果是俩个线程同时访问这个方法,第一确定不了顺序,就是随机配对,得不到想要的东西,任意的组合,所以说原子保证不了线程的安全.
如果想要得到解决,原子改成非原子
或者:
- (void)update:(User*)user strName:(NSString*)strName strTitle:(NSString*)title
{
@synchronized(user){ 锁住了,顺序就有了,得到解决
user.name = strName;
user.title = title;
}
}
好多开源的第三方就会出现这样的问题,可以解决处理。
网友评论