iOS 属性修饰符

@property 有两个的作用:一是自动生成私有属性(一般是下划线+属性名),而是自动生成 gettersetter 方法。
声明属性时,紧跟在 @property 之后的属性修饰符则描述了自动生成 gettersetter 方法的规则。

根据MRC和ARC划分属性修饰符的使用范围:
MRC:nonatomic,atomic,retain,assign,copy,readwrite,readonly
ARC:nonatomic,atomic,strong,weak,assign,copy,readwrite,readonly

  • nonatomic
    • nonatomic 表示非原子属性
      • 并发访问性能高,但是访问不安全
        • 它直接访问内存中的地址,不关心其他线程是否在改变这个值,并且中间没有死锁保护;所以可能拿不到完整的值
  • atomic
    • atomic 表示原子属性
      • 系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响
        • 系统生成的 getter/setter 方法中,使用了 @synchronized(self)
        • 如果一个线程正在执行 getter/setter,其他线程就得等待
      • 如果有另一个线程同时在调 [property release],那可能就会crash,因为 release 不受 getter/setter 操作的限制。
        • 也就是说,atomic 修饰的属性只能说是读/写安全的,但并不是线程安全的
          • 因为别的线程还能进行读写之外的其他操作。
          • 线程安全需要开发者自己来保证。
    • 系统默认的属性是 atomic
  • strong
    • strong 表示对对象的强引用
      • 强引用时,引用计数会 +1
      • 给 strong 属性赋值时,setter 方法中会先 release 旧值再 retain 新值并赋值
      • 两个对象之间相互强引用会造成循环引用,内存泄漏
  • weak
    • weak 表示对象的弱引用
      • 弱引用时,不会使传入的对象计数+1

      • 被其修饰的对象随时可能被系统销毁回收

        • 当该对象的引用计数为 0,则会被回收,对象被释放以后,weak 指针会被自动设置为 nil

          在OC的运行时环境中,维护了一种 weak 表(哈希表)
          这张哈希表用对象的首地址作为 key,用 weak 指针自身的地址组成的数组作为 value
          当对象被释放后,通过这个对象的起始地址来找到所有指向它的 weak 指针,并将它们指向nil

      • weak 多用于避免循环引用

  • assign
    • assign 主要用于修饰基本数据类型
      • 包括OC基本数据类型(NSInteger,CGFloat)和C数据类型(int, float, double, char)
    • 基本数据类型存储在栈中,内存不用程序员管理。
    • assign 也可以修饰对象,但是当对象被释放后,指针依然指向之前的内存地址。
      - 此时,访问被释放的地址就会 crash
      • 这个已经被释放了的对象被称为 僵尸对象
    • assign 在 MRC 和 ARC 下都可以使用
  • retain
    • 在 MRC 下使用,用于修饰对象
    • 被 retain 修饰的对象,retainCount要+1
    • retain 只能修饰 OC 对象,不能修饰非 OC 对象(如 Core Foundation 对象)
      • retain 会增加对象的引用计数,而基本数据类型或者 Core Foundation 对象都没有引用计数
    • 赋值时,先 release 旧值,再 retain 新值
  • copy
    • copy 表示在赋值时使用传入值的一份拷贝
      • 赋值时,创建了一个新的对象,并将传入对象的值全部拷贝到新对象
      • 赋值后,新对象的 retainCount 为 1,而旧对象的 retainCount 不变
    • 只能修饰对象类型,不能修饰基础数据类型
    • 用copy修饰的对象,必须实现
      NSCopying 协议,也就是实现方法 -(id)copyWithZone:(nullable NSZone *)zone
      • 系统自动生成的 setter 方法中会调用这个方法
      • 至于 copy 是深拷贝还是浅拷贝完全是看 copyWithZone 的实现方式,copy 修饰符和深拷贝、浅拷贝没有关系
    • 一般用于修饰不可变的属性(NSArray,NSDictionary,NSString,block)
      • 即使用 copy 修饰 NSMutableArray,将一个可变 NSMutableArray 赋值给 copy 修饰的属性也会变成不可变数组 NSArray
        • 若 a 被 copy 修饰,则 a = b 等价于 a = [b copy]
      • 为什么要用 copy 修饰 NSString ?
        如果用 retain 修饰 NSString,
        当把 NSMutableString 赋值给 NSString 时,只是拷贝了指针;
        如果赋值后源字符串改变,这个属性值也跟着改变。(不可控)
        如果用 copy 修饰 NSString,
        当把 NSMutableString 赋值给 NSString 时,会生成一份拷贝内容;
        即使赋值后源字符串改变,这个属性值也不会改变。(保证了安全)
  • readwrite
    • readwrite 表示该属性可读可写
    • 系统会自动创建 setter 和 getter 方法
    • readwrite 是默认的属性修饰符
  • readonly
    • readonly 表示该属性只可读,不可写
    • 只会生成get方法
    • 对用 readonly 修饰的属性赋值时,编译器会报错提示:“Assignment to readonly property”。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 一. 成员变量,实例变量,属性变量成员变量 : 用在类的内部,无须与外部接触.成员变量默认是被保护的,所以不会有s...
    Mccc_阅读 2,065评论 0 8
  • iOS属性问题 属性修饰符的作用 iOS5之前是MRC, 内存需要程序员管理,iOS之后是ARC,除非特殊情况(例...
    自律_自强_通达阅读 934评论 0 1
  • 前言 很多刚接触iOS的朋友,对property的可选参数如何使用,什么情况下使用哪种选项不了解,也问了我很多这方...
    G_GUI阅读 960评论 0 0
  • iOS开发中属性修饰符基本上每天都会打交道,网上总结也很多,本文按照实际开发的角度简单介绍一下属性修饰符,属性修饰...
    FlyElephant阅读 2,267评论 0 4
  • 一.写在前面的话 为什么要把他排在第一位?这是有原因的,因为这破玩意在开发中很少会引起注意,一般人都是一带而过,不...
    objcat阅读 361评论 0 3