@property copy strong retain assign atomic readonly setter

这里写图片描述

1. 线程安全(系统默认)

atomic
1.atomic原子性指的是一个操作不可以被CPU中途暂停,然后再调度。即不能被中断,要么就执行完,要么就不执行
2.atomic是自旋锁,Objc使用的一种线程保护技术。当上一线程没有执行完毕的时候(被锁住),下一个线程会一直等待(不会进入睡眠状态),当上衣线程任务执行完毕,下一线程立即执行。它区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当被上一线程执行完毕后,会被唤醒,然后再执行。
3.atomic只给setter方法上锁,getter不会加锁
4.atomic需要消耗大量的系统资源,执行效率低

nonatomic
非原子性,非线程安全,多个线程可以同时对其进行访问,使用该属性编译器会少生成加锁代码,提高性能和效率,使用频率高,一般都是放弃安全,提高性能

所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,nonatomic是一个非常好的选择。

**2. 访问权限 **

readonly:只读,所修饰的属性只有getter
readwrite:读写,所修饰属性既有getter又有setter

**3. 内存管理 **

1>、assign
简单赋值,不更改索引计数;适用于基本数据类型:NSInterger、CGFloat和C数据类型 int、float等


2>、strong:和retain
相同点:都是针对对象类型进行内存管理。当给对象类型使用此修饰符时,setter方法会先将旧的对象属性release掉,再将新的对象赋值给属性并对该对象进行一次retain操作,两者都会增加对象的引用计数。
不同点:strong 一般用于ARC环境,retain用于MRC环境


3>、assign :和 weak
相同点:都不牵扯到内存管理,也不会增加引用计数。
不同点:assign既可修饰基本数据类型也可修饰OC对象;但如果修饰对象类型指向的是一个强指针,当它指向的这个指针释放后,它仍指向这块内存,必须手动给其置为nil,否则就会产生野指针,如果还通过此指针操作那块内存,便会导致EXC_BAD_ACCESS错误,调用了已经释放的内存空间;
weak只能修饰OC对象,且相对assign比较安全,如果指向的对象消失了,那么它会自动置为nil,不会产生野指针。
弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。


4>、weak
弱引用除了不决定对象的存亡外,其它与强引用相同。即使一个对象被持有无数个弱引用,只要没有强引用指向它,还是会被清除。
从storyboard或xib上创建的控件,在控件放在view上的时候,就形成了如下的引用关系,以UIButton为例:

UIViewController->UIView->subView->UIButton

为这个UIButton声明一个weak属性
@property (nonatomic, weak) IBOutlet UIButton *btn;

// IBOutlet的属性一般可以设为weak是因为它已经被view引用了,除非view被释放,否则IBOutlet的属性也不会被释放,IBOutlet属性的生命周期和view应该是一致的,所以IBOutlet属性一般设为weak。

//代理必须是weak,因为代理一般都是指向控制器,会造成循环引用,无法释放,造成内存泄露

5>、copy: 和 strong
(1)strong是强引用,指向的是同一个内存地址。
(2)copy是为了减少对上下文的依赖而引入的机制,可以理解为内容的拷贝,会另外开辟内存空间,指针指向一个不同的内存地址,copy返回的是一个不可变对象,如果使用strong修饰可变对象,那么对象就会有可能被不经意间修改,有时不是我们想要的,而copy不会发生这种意外。
(3)当用copy修饰,setter方法中会自动判断,如果来源是不可变的,那么和strong一样,进行浅拷贝,会增加其引用计数;如果来源是可变的就进行深拷贝,不会增加其引用计数。

这里写图片描述

例:

@property (nonatomic, copy) NSString *coName;
@property (nonatomic, strong) NSString *stroName;


NSMutableString *mStr = [NSMutableString stringWithString:@"张三"];
self.coName = mStr;
self.stroName = mStr;

NSLog(@"用copy修饰第1次打印的值%@",self.coName);
NSLog(@"用strong修饰第1次打印的值%@",self.stroName);

[mStr appendString:@"风"];
/*
 因为coName使用了copy修饰,mStr通过copy得到了一个新的对象赋值给self.coName,
 这样再修改mStr就跟self.coName没关系了,只有直接对self.coName进行赋值才能改变它的值,
 这样就保证了程序的封装性
 */

NSLog(@"用copy修饰第2次打印的值%@",self.coName);
NSLog(@"用strong修饰第2次打印的值%@",self.stroName);

打印结果:

用copy修饰第1次打印的值张三
用strong修饰第1次打印的值张三
用copy修饰第2次打印的值张三
用strong修饰第2次打印的值张三风

**4. 指定settergetter **

就是不用系统的settergetter,替换成自定义的函数

tips:
http://blog.csdn.net/qq_32744055/article/details/53443805
https://www.zhihu.com/question/20102376
https://www.jianshu.com/p/da797678ef95
https://www.zhihu.com/question/29927614?sort=created

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值