首页 > 移动端 > Object-C 属性修饰符使用祥解

Object-C 属性修饰符使用祥解

Object-C属性定义@property修饰符主要有

  • atomic
  • nonatomic
  • readonly
  • readwrite
  • assign
  • retain
  • copy
  • getter
  • setter
它们之间可以组合使用,多个修饰符用逗号分隔,当然互斥的除外。声明属性时可以不必指定修饰符,没有指定修改符的编辑时使用默认参数。
下面将对各修饰符作祥细介绍:
  • atomic 和 nonatomic, 原子还是非原子性操作,前者为默认,表示属 性是原子的,支持多线程并发访问(实际就是 setter 的实现中加入了同步锁),后者是非原 子的,也就是适合在非多线程的环境提升效率(因为 setter 中没有同步锁的代码)。没有特别的多线程要求用 nonatomic 有助于提高性能。
  • readonly, readwrite 表示属性的可读写特性
  • retain, assign, copy 针对对象使用,根据 setter 方法内部实现时对传入的对象的持有方式。retain 会增加引用计数,强引用类型, assign 是给变量直接赋值,弱引用类型,也是默认值, copy 是把 setter 的参数复制一份再赋给成员变量。注意它们对引用计数产生的影响,如果外部不再使用的话,用了 retain 或 copy 赋值的可以release 掉那个对象。
  • getter=getterName 和 setter=setterName, 显式设置 getter/setter 方法名, 未指定它们时 Objective-C 会为我们生成默认的 setter/getter 方法, 有一定的规则,
    比如上面的 NSString* gender 属性生成默认的setter 方法是: -(void) setGender:(NSString *);
    getter 方法是: -(NSString *) gender;
    想看看 Objective-C 为我们生成什么 getter/setter 方法, 不用点号来隐式调用 setter/getter 方法,而是显式的用 [unmi setGender] 或 [unmi gender], 输入式这两个方法会自动提示出来的。注意这里的 getter 方法名并非是像 Java 的 getGender, 而是和属性名同.
    假如你想要自己个性的 getter/setter 方法,比如写成 @property(getter=getGender, setter=setSex:) NSString* gender; 那么相应的就会生成:
      setter 方法是: -(void) setSex:(NSString *);
      getter 方法是: -(NSString *) getGender;
    在 Xcode 中 esc unmi 就能看到相应的 setter/getter 方法名的. 可以只用其中一个了,那另一个保持默认。这两个较少用,用途就是可用来生成自己个性的但要符合某个范围内规范的 setter/getter 方法。像 @property(getter = isOnline) BOOL online; 则会生成 -(BOOL) isOnline; 这样的 getter 方法,而不是 -(BOOL) online; 当然我们也很少且不推荐直接调用 getter/setter 方法,而是用点号的方式,但是有意思的去覆盖 getter/setter 方法时就较象明确了。

那么什么时候用assign、什么时候用retain和copy呢?
推荐做法是NSString用copy,delegate用assign(且一定要用assign,不要问为什么,只管去用就是了,以后你会明白的),非objc数据类型,比如int,float等基本数据类型用assign(默认就是assign),而其它objc类型,比如NSArray,NSDate用retain。

顺便说明一下@property 中的 retain/assign/copy 对应 setter 方法的内部实现:

 
//retain 时:
-(void) setAddress: (Address *) address {
     if(_address){
         [_address release];
     }
     _address = [address retain];
 } 

//assign 时:
 -(void) setAddress: (Address *) address {
     self.address = address;
 } 

//copy 时:
 -(void) setAddress: (Address *) address {
     if(_address){
         [_address release];
     }
     self.address = [address copyWithZone: zone];// Address 必须实现 NSCoping 协议
 }


参考资料
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
http://www.cnblogs.com/zilongshanren/archive/2011/08/03/2125728.html

Objective-C 的属性与合成方法使用详解

分类: 移动端 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.

=5加7(必填)请输入两数相加的结果。