iOS 属性修饰词

一、 property有哪些属性修饰词?
atomic   nonatomic   strong   weak   copy   assign   readwrite   readonly 
getter    setter    unsafe_unretained    nononull    nullable    null_resetable

写在后面:
Q:ARC下property的默认关键字是?
A:@property()CGFloat marginLeft; // 修饰基本数据类型默认的关键字是atomicreadwriteassign
@property()NSObject *obj; // 修饰普通OC对象默认的关键字是atomicreadwritestrong



二、 weakassign的区别

· weak 只可以修饰对象。如果修饰基本数据类型,编译器会报错 - “property with ‘weak’ attribute must be of object type”。
weak 适用于delegate和block等引用类型,还有自定义IBOutlet控件也使用weak修饰,不会导致野指针问题,也不会循环引用,非常安全。
· assign 可修饰基本数据类型,也可修饰对象。但是当修饰对象类型时,MRC时代使用unsafe_unretained修饰。ARC下使用assign修饰对象也可看作是unsafe_unretained,这就可能会产生野指针。

Q:`weak`不会造成野指针问题的原因:
A:`weak` 不会产生野指针问题,因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。
Q:`assign`可能会造成野指针问题的原因:
A:`assign` 如果修饰对象,会产生野指针问题;如果修饰基本数据类型则是安全的。修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。

写在后面:
Q: weak修饰的对象释放后,指针被置为nil的过程?
A:runtime对注册的类,会进行布局,对于weak对象会放入一个hash表中,用weak指向的对象的内存地址作为key,当次对象的引用计数为0时会dealloc,假如weak指向的对象的内存地址是a,那么就会以a为键,在这个hash表中搜索,找到所有以a为键的weak对象,从而置为nil


三、strongweak的区别

·weak是弱引用,strong是强引用,strong修饰的属性一般不会自动释放;
· 在OC实际开发中属性对象一般用strong来修饰,在使用懒加载定义控件的时候,一般也用strong。
·在使用 sb 或者 xib 给控件拖线的时候,拖出来的属性都是用 weak 修饰的

写在后面:
Q:使用 sb 或者 xib 给控件拖线的时候,拖出来的属性都是用 weak 修饰的 ?
@property (weak, nonatomic) IBOutlet UILabel *label;
A:在向 xib 或者 sb 里面添加控件的时候,添加的子视图是添加到了根视图View上面, 而控制器对其根视图 View默认是强引用的,当我们的子控件添加到View上面的时候,[self.view addSubView: self.mainView] ;这个方法会对添加的控件进行强引用,如果在用 strong 对添加的子控件进行修饰的话,相当于有两条强指针对子控件进行强引用, 为了避免这种情况,所以用 weak 修饰.


四、什么情况下使用copy关键字?
  1. 修饰NSStringNSArrayNSDictionaryNSNumber,NSString等经常使用copy关键字:
    因为他们有相应的可变类型。
  • 注意:NSMutableArrayNSMutableDictionaryNSMutableString等经常使用strong关键字
  • 理由:
    -- NSArray类型使用copy修饰,防止值和类型被意外修改; 使用strong修饰时,值和类型可能会被修改;
    -- NSMutableArray使用strong修饰,因为如果使用copy修饰的话,创建的是不可变对象,再对不可变对象执行增删改操作就会crash.
  1. block也经常使用copy关键字:
    block使用copy是从MRC上遗留下来的传统,在MRC中,方法内部的block是放在栈区的,使用copy可以把它放在堆区;在ARC中,使用copyweak都可以。

写在后面:
Q:block有什么类型,都存放在那里?
A:block一共有3种类型。
1._NSConcreateGloubalBlock,全局的静态block,类似函数,如果block里面不获取任何外部变量,或者变量是全局作用域时,如成员变量属性,那么就是global类型。
2._NSConcreateStackBlock,保存在栈中的block,栈都是由系统管理内存,当函数返回时会被销毁,__block类型的变量也会被销毁,为了不被销毁。block会将block__block变量从栈拷贝到堆。
3.__NSConcreateMallocBlock,保存在堆中的block,堆内存由开发人员控制,当引用计数为0时被销毁。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,174评论 1 32
  • 属性修饰符简述 ios5之前是MRC,内存需要程序员进行管理,ios5之后是ARC,除非特殊情况,比如C框架或者循...
    咖啡绿茶1991阅读 789评论 0 2
  • 很多人讲属性修饰词的时候,喜欢从字面或者定义的角度介绍它们间的区别。这篇文章,我们侧重从修饰词对setter方法的...
    小码僧阅读 3,472评论 1 18
  • 今天早上和小伙伴交流上周的培训收获,她说她觉得我的学习能力很强,比她吸收快还能表达出来、知道怎么用,问我是不...
    火韦木南阅读 533评论 2 1
  • 【作者简介】 我是一个在农村出生、成长的普通孩子,家境并不富裕。我不高不漂亮不聪明,但也不算特别差。我经常想,像我...
    妤淑阅读 539评论 2 2