戳我
戳我
文章目录
  1. 属性的修饰符解析
    1. 属性的修饰符
    2. weak & assign
    3. copy关键字的使用

属性的修饰符解析

属性的修饰符解析

属性的修饰符

  1. 线程安全的: atomic, nonatomic
  2. 访问权限的: readonly, readwrite
  3. 内存管理(ARC): assign,strong,weak,copy
  4. 内存管理(MRC):assign, retain,copy
  5. 指定方法名称: setter= getter=

默认的修饰符是:

  • 基本数据类型使用atomic, readwrite, assign.
  • 对于普通的Objective-C对象使用atomic, readwrite, strong.

weak & assign

assign修饰基本数据类型和结构体, weak修饰一个对象


assign修饰的对象编译时会产生一个警告:Assigning retained object to unsafe_unretained variable; object will be released after assignment(Assign修饰的对象无法被保留). 并且在释放之后指针的地址还是存在的, 也就是说指针并没有被置为nil, 造成野指针. 对象分配一般分配在堆上的某块内存(详见内存分配), 如果在后续的内存分配中, 刚好分到了这块地址, 程序就会导致EXC_BAD_ACCESS(调用已释放的内存空间)崩溃掉.

assign修饰的基本数据类型或者结构体因为技术数据类型和结构体一般分配在栈上, 栈的内存会由系统自己自动处理, 不会造成野指针.


weak修饰的对象在释放之后, 指针会被置为nil, 所以一般弱引用指的就是用weak.

weak主要使用在以下两个方面:

  • 在ARC下, 有可能出现循环引用的地方, 比如delegate
    @property (nonatomic, weak) id XXXDelegate;
  • 自身已经被强引用过一次, 比如xib文件汇总的属性
    @property (nonatomic, weak) IBOutlet UIButton *button;

copy关键字的使用

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

copy关键字主要有以下使用场景:

  • 不确定赋值过程中用的是可变还是不可变的变量. 例如NSString, NSArray, NSDictionary等等常使用关键字copy, 因为他们有对应的可变类型.关于copy和strong的详解
  • block也经常使用copy关键字. 用copy修饰block时要知道是在ARC还是MRC.
    • ARC下只要block访问了外部局部变量, block就会放到堆区里面, 使用strong或者copy都可以, 但是strong的性能可能会更好.
    • MRC下, 如果block访问外部局部变量, block是在栈区的. 如果block访问了一个整个APP生命周期都存在的变量, 那他肯定在全局区. 只有使用copy属性才能把block放到堆区.

参考内容:
1.@property 关键字的区别详解
2.iOS开发中ARC下的assign和weak区别
3.整理一下OC中的那些属性修饰符
4.@property 后面可以有哪些修饰符