(0022)iOS 开发之@property的属性Weak Strong的深入学习

最近做项目发现经常有一些疑惑,发现一些天天写的代码理解的不是很清楚,于是准备对一些问题进行彻底的总结、深究,以此夯实基础!记录在案。

 

1.@property 介绍:

  • 与@synthesize配对使用,不过后来@synthesize 也省去了。
  • @synthesize则是用来生成对应声明方法的实现。现在推荐省去,编译器会自动帮你加上getter 和 setter 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量。


2.atomic与nonatomic

  • atomic的意思就是setter/getter这个函数是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁一样。
  • nonatomic不保证setter/getter的原子性,所以你可能会取到不完整的东西。 比如setter函数里面改变两个成员变量,如果你用nonatomic的话,getter可能会取到只更改了其中一个变量时候的状态,这样取到的东西会有问题。
  • atomic:默认是atomic,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
  • nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。另外由于不涉及锁操作,所以它执行相对快点。
  • copy

     复制内容(深复制)。如果调用copy的是数组,则为指针复制浅复制),仅仅复制子元素的指针。

  @property  (nonatomic,copy)NSString  *title;

    @property (nonatomic, copy) NSMutableArray *myArray;//not recommended

    @property (nonatomic, copy) SomeBlockType someBlock;


3.使用规则

    assign: 对基本数据类型(NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)

    copy: 对NSString block 

    retain:对其他NSObject及其子类

    weak: 对NSObject对象 、delegate 。修饰的对象在释放之后,指针地址会被置为nil。弱引用


4.区别


4.1  assign与weak区别

  • assign适用于基本数据类型,weak是适用于NSObject对象,并且是一个弱引用。
  • assign其实也可以用来修饰对象。那么我们为什么不用它修饰对象呢?因为被assign修饰的对象(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,造成野指针。对象一般分配在堆上的某块内存,如果在后续的内存分配中,刚好分到了这块地址,程序就会崩溃掉。
  • 那为什么可以用assign修饰基本数据类型?因为基础数据类型一般分配在栈上,栈的内存会由系统自己自动处理,不会造成野指针。


weak修饰的对象在释放之后,指针地址会被置为nil。所以一般弱引用就是用weak。weak使用场景:

  • 在ARC中,在有可能出现循环引用的时,往往要让其中一端使用weak来解决,比如: delegate。
  • 自身已经对它进行一次强引用,没有必要再强引用一次时也会使用weak。比如:自定义 IBOutlet控件属性一般也使用weak,当然也可以使用strong。


4.2  strong 与copy的区别

strong 与copy都会使引用计数加1,但strong是两个指针指向同一个内存地址,copy会在内存里拷贝一份对象,两个指针指向不同的内存地址。


  1. 4.3  copy与retain:
  2. copy其实是建立了一个相同的对象,而retain不是;
  3. copy是内容拷贝,retain是指针拷贝;
  4. copy是内容的拷贝 ,对于像NSString,的确是这样;但copy的是一个NSArray 时,只是copy了指向array中相对应元素的指针,这便是所谓的"浅复制”。


4.4 __block与__weak的区别

  • __block是用来修饰一个变量,这个变量就可以在block中被修改;__block:使用 __block修饰的变量在block代码块中会被retain(ARC下会retain,MRC下不会retain);
  • __weak:使用__weak修饰的变量不会在block代码块中被retain;
  • 在ARC下,要避免block出现循环引用 __weak typedof(self)weakSelf = self;


5. block变量定义时为什么用copy?block是放在哪里的

  • block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,可能被随时回收,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。通过copy可以把block拷贝(copy)到堆,保证block的声明域外使用。


特别注意:在把block放到集合类当中去的时候,如果直接把生成的block放入到集合类中,是无法在其他地方使用block,必须要对block进行copy。

[array addObject:[[^{

    NSLog(@"hello!");

} copy] autorelease]];


6.为什么建议UI控件一般使用weak?

首先我们从controller来看,controller是被系统用强指针引用着,所以如果 controller 还存在,里面的子控件也会存在,那么controller 强引用着它的view(从 controller 中它的 view 的属性是 retain 看出来的,retain 就是 MRC 年代的强引用),那么 view 又强引用着它的数组对象subviews,数组对象又引用着它所包含的数组内容,所以当我们创建出来一个UI控件并将其加入到subviews的时候,它就会被一个强指针所引用着,我们可以简化一下这个过程:--> Controller --> View --> Subviews(数组) --> 数组内容(添加到其中的UI控件)


  • dealloc 可以做哪些操作

    移除观察者observers

    注销通知notification

    设置非weak的delegate为nil    取消timer


参考与感谢:

http://www.jianshu.com/p/3e0f12e5faaa

http://blog.csdn.net/dyllove98/article/details/41681851

http://www.cnblogs.com/iCocos/p/4462744.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值