@property关键字和参数详解

来源:互联网 发布:java集合类是干啥的 编辑:程序博客网 时间:2024/05/19 19:41

总结一下@property所有的参数(本文的所有内容都是从前面的日志中抽取出来的,但是只涉及@property参数)

1.@property和@synthesize关键字

----------@property:可以自动生成某个成员变量的settergetter声明

@property int age;//相当于下面两句- (void)setAge:(int)age;- (int)age;
----------@synthesize自动生成age(property)settergetter实现,并会访问_age这个成员变量

@synthesize age = _age;//相当于下面两句- (void)setAge:(int)age{    _age = age;}- (int)age{    return _age;}

√如果_age这个成员变量不存在 ,就会自动生成@private类型的_age的变量,意味着类声明中没有_age,而在类实现中直接使用@synthesize age = _age;也可以。

√如果不指定值@synthesize age 就会访问age这个成员变量,意味着这一句相当于@synthesize age =  age;

***************生成get和set方法的最简写法(Xcode4.4开始支持)

@property int age;
一句完成的工作(3个):

√1.添加成员变量_age(private):

@privateint _age;

√2.声明gettersetter方法

@property int age;
√3.实现gettersetter方法

@synthesize age = _age;
注意点:

----如果自己在@implementation中写了settergetter,但是没有在@interface中声明_age成员变量(这种情况的可能应该是疏忽大意),@property int age;不会再帮助生成_age成员变量;

----如果只是在@implementation中写了setter或者getter两个方法中的一个,@property int age;依然会帮助生成_age成员变量和两一个方法。

因此有下面两种简化代码的方式(三种方式):

方式一:

在@interface中声明属性 和使用@property生成getter和setter声明

在@implementation中使用@synthesize生成getter和setter的实现

[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Person : NSObject  
  4. {  
  5.     int _age;  
  6.     int _height;  
  7. }  
  8. @property int age;  
  9. @property int height;  
  10. @end  

[objc] view plaincopy
  1. #import "Person.h"  
  2.   
  3. @implementation Person  
  4. @synthesize age = _age;  
  5. @synthesize height = _height;  
  6. @end  

方式二再简单一点(Xcode4.4之后):

在@interface中声明属性 和使用@property生成getter和setter声明并在@implementation中生成实现

[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Person : NSObject  
  4. {  
  5.     int _age;  
  6.     int _height;  
  7. }  
  8. @property int age;  
  9. @property int height;  
  10. @end  

方式三,最简单的(Xcode4.4之后):
在@interface中使用@propert生成属性,生成getter和setter声明并在@implementation中生成实现

[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Person : NSObject  
  4. @property int age;  
  5. @property int height;  
  6. @end  

2.@property参数详解

√1.内存管理相关的参数(三择一)

retain: release旧值、retain新值(适用于OC对象类型)

assign:直接赋值(默认,适用于非OC对象类型)

copy:release旧值, copy新值


√2.是否要生成set方法

readwrite:同时生成settergetter的声明和实现(默认)

readonly:只会生成getter的声明和实现


√3.多线程管理

nonatomic:性能高(一般就用这个,非原子性)

atomic:性能低(默认)


√4.settergetter方法的名称

setter:决定了set方法的名称,一定要由个冒号:

getter:决定了get方法的名称(一般用在BOOL类型的属性值)

注意:

当成员变量类型为BOOL类型时,get方法方法名一般以is开头

[objc] view plaincopy
  1. @property (getter=isRich) BOOL rich;  

3.retain参数的引入及重要性 (retain、assign、copy的使用场景和区别):

利用@property参数对内存进行管理时,默认情况下@property生成set方法只是简单的赋值操作:

在Person类的声明中添加这行代码

[objc] view plaincopy
  1. @property Book *book;  
意味着编译器在实现中帮助生成的set方法是这样的

[objc] view plaincopy
  1. - (void)setBook:(Book *)book  
  2. {  
  3.     _book = book;  
  4. }  
对于对象类型,这样显然是不合理的(内存管理中讨论过),若要为@property添加retain关键字:

[objc] view plaincopy
  1. @property (retainBook *book;  

编译器便会添加这样的set方法:

- (void)setBook:(Book *)book  {      if (book != _book)      {          [_book release];          _book = [book retain];      }  }
可见retain参数的作用: 生成的set方法里面,release旧值,release新值。多么完美的编译器特性。

因此开发中对于成员变量是类类型时@property要添加retain参数,需要注意的是使用NSString作为成员变量类型时也要添加,因为NSString也是了类类型。

****************对于基本的数据类型直接使用assign参数即可。

****************下面是至关重要的copy参数

copy:对于有对应的可变类型的对象类型(NSStringNSArray等都有对应的Mutable类型)使用copy,它的作用是:在生成的set方法里面release旧值,copy新值,为什么要这样使用呢.看看我的例子:

    Person类的声明中是这样的:

@property (retain) NSString *name;
但是书写程序时可能有时候为了便于操作传入了NSMutableString类型的name,像下面的程序
NSMutableString *name = [NSMutableString stringWithString:@"jack"]; // 使用NSMutableString类型定义了name    Person *p = [[Person alloc] init];p.name =name; // 给name传入的时NSMutableString类型    [name appendString:@"son"];NSLog(@"%@", p.name); // 若使用retain 则p.name被莫名其妙地改变了,最好使用copy
这时候程序的输出结果是:jackson,显然我们并不希望name的改变影响到p.name的值。

如果将Person.h中的@property (retain) NSString *name;改为

@property (copy) NSString *name;
,则程序输出的结果是:jack。因此这种情况最好使用copy

4.使用了arc之后(刚才所说得全是非arc的情况)

1>.@property的参数(非arc内存管理参数有:retain、assign、copy,而对于arc的情况,则对应下面的四个参数)

 strong:成员变量是强指针 (适用于OC对象类型)

 weak:成员变量是弱指针 (使用于OC对象类型)

 assign:适用于非OC对象类型

 copy:适用于可变的对象类型。

2.>.以前的retain改为用strong其他不变(copy和assign)

5.类的循环引用

 当两端循环引用的时候,解决方案:

 1.使用ARC

 修改@property参数:一端用strong,一端用weak(这也是我目前发现的weak唯一的用途)

 2.ARC

修改@property参数: 一端用retain另一端用assign


0 0
原创粉丝点击