OC @property 指示符assign、atomic、copy、retain、strong、week、等

简介:

在使用@property定义property时可以在@property与类型之间用括号添加一些额外的指示符,常用的指示符有assign、atomic、copy、retain、strong、week、等。下面对它们的用途和常常对应的属性讲解一下。

  • assign:该指示符号对属性只是简单的赋值,不更改引用计数。常用于NSInteger等OC基础类型,以及short、int、double、结构体等C数据类型,因为这些类型不存在被内存回收的问题。

  • atomic、nonatomic:指定setter和getter是否是原子操作,即是否线程安全。如果是atomic,那么存取方法都是线程安全的,即某一线程访问存或者取方法,其他线程不可以进入该存、取方法。nonatomic则不具备线程安全的功能。需要指出的是atomic是默认值,可以保证数据的完整性,但是相应的降低了性能,所以在单线程环境中建议使用nonatomic来提升性能。

  • copy:如果使用copy指示符,当调用setter方法对成员变量赋值时,会将被赋值的对象复制的一个副本,再将该副本给成员变量,相应的原先的被赋值的对象的引用计数加1。当成员变量的类型是可变类型,或其子类是可变类型,被赋值的对象在赋值后有可能再被修改,如果不需要这种修改,则可以考虑copy指示符。

  • getter、setter:用于为getter方法、setter方法指定自定义方法名。比如getter=myName,setter=setName:,我们可以看到setter方法后面有一个(:),这是因为我们需要在后面添加参数。

  • readonly、readwrite:readonly指示系统只合成getter方法,不合成setter方法;readwrite是默认值,指示系统需要合成setter方法和getter方法。

  • retain:当把某个对象赋值给该属性时,该属性原来所引用的对象的引用计数减1,被赋值对象的引用计数加1。在未启用ARC机制的的情况下,retain可以保证一个对象的引用计数大于1时,该对象不会被回收。启用ARC后一般较少使用retain

  • strong、weak:strong指示符该属性对被赋值对象持有强引用,而weak指示符指定该属性对被赋值对象持有弱引用。强引用的意思是:只要该强引用指向被赋值的对象,那么该对象就不会自动回收。弱引用的意思是:即使该弱引用指向被赋值的对象,该对象也可能被回收。如果不希望对象被回收,可以使用strong指示符。如果需要保证程序性能,避免内存溢出,可以使用weak,内存一旦被回收,指针会被赋值为nil。

  • unsafe_unretained:与weak不同,被unsafe_unretained指针所引用的对象被回收后,unsafe_unretained指针不会被赋为nil,可能会导致程序出错。

1、atomic是默认行为,assign是默认行为,readwrite是默认行为

2、推荐做法是NSString用copy

3、delegate用assign(且一定要用assign)

4、非objc数据类型,比如int,float等基本数据类型用assign(默认就是assign)

5、其它objc类型,比如NSArray,NSDate用retain。


OC中提供了4个访问控制符:@private @package @protected @public。

@private(当前类访问权限):成员只能在当前类内部可以访问,在类实现部分定义的成员变量相当于默认使用了这种访问权限。

@package(同映像访问权限):成员可以在当前类或和当前类实现的同一映像中使用。同一映像就是编译后生成的同一框架或同一个执行文件。

@protected(子类访问权限):成员可以在当前类和当前类的子类中访问。在类接口部分定义的成员变量默认是这种访问权限。

@public(公共访问权限):成员可以在任意地方访问。


@private

@package

@protected

@public

同一个类中



同一个映像中





子类中





全局范围





下面使用@private来实现Person类,用来封装Person的2个属性,并将方法暴露出来:

[objc] view plain copy

 在CODE上查看代码片派生到我的代码片

  1. #import <Foundation/Foundation.h>  

  2. @interface Person : NSObject{  

  3.     //使用@private限制成员变量  

  4. @private  

  5.     NSString* _name;  

  6.     int _age;  

  7. }  

  8. //声明_name的set方法  

  9. -(void)setName:(NSString*)name;  

  10. //声明_name的get方法  

  11. -(NSString*)name;  

  12. //声明_age的set方法  

  13. -(void)setAge:(int)age;  

  14. //声明_age的get方法  

  15. -(int)age;  

  16. @end  

  17.   

  18.   

  19. #import "Person.h"  

  20. @implementation Person  

  21. //声明_name的set方法  

  22. -(void)setName:(NSString*)name{  

  23.     _name = name;  

  24. }  

  25. //声明_name的get方法  

  26. -(NSString*)name{  

  27.     return _name;  

  28. }  

  29. //声明_age的set方法  

  30. -(void)setAge:(int)age{  

  31.     _age = age;  

  32. }  

  33. //声明_age的get方法  

  34. -(int)age{  

  35.     return _age;  

  36. }  

  37. @end  

  38.   

  39. #import <Foundation/Foundation.h>  

  40. #import "Person.h"  

  41. int main(int argc, const charchar * argv[]) {  

  42.     @autoreleasepool {  

  43.         Person* person = [[Person alloc]init];  

  44.         //报错,age已经被封装起来,对外不可见  

  45.         //person->_age = 10;  

  46.         [person setAge:10];  

  47.         NSLog(@"age:%d",[person age]);  

  48.     }  

  49.     return 0;  

  50. }  












本文转自ljianbing51CTO博客,原文链接: http://blog.51cto.com/ljianbing/1864902,如需转载请自行联系原作者





相关文章
|
C++
Effective C++学习笔记之copy构造函数和default函数和copy赋值函数(operator=)
Effective C++学习笔记之copy构造函数和default函数和copy赋值函数(operator=)
150 0
|
JavaScript
void mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property b
void mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: vue项目示例,请参考甄佰 单向数据流所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
3422 0
__attribute__((weak)) zz
http://blog.chinaunix.net/uid-7828352-id-4477460.html 情况是这样的,碰到一个棘手的问题:我们不确定外部模块是否提供一个函数func,但是我们不得不用这个函数,即自己模块的代码必须用到func函数: extern int func(void); int a = func(); if( a > .....) { .......... } 我们不知道func函数是否被定义了 这会导致2个结果: 1:外部存在这个函数func,并且EXPORT_SYMBOL(func),那么在我自己的模块使用这个函数func,正确。
1146 0
笔记:Six Pointers for Creating Strong Operational Business Values
这篇文章讲的是关于怎样创造强壮而且可操作的商业价值的六点内容,有些新意,不过最后意思的是这张图,这张图一个自上而下的组织的示意图,搞得好传神,够我笑一天的: 其他的: Key Takeaways Businesses need to take into account that the future will be driven by a millennial workforce.
1943 0