@先来介绍一下property中各个属性的含义:
1.assign:这个属性一般用来处理基础类型,比如int、float等等,如果你声明的属性是基础类型的话,assign是默认的,你可以不加这个属性!(一个常见的例外是delegate的set方法通常设为assign,这是为了避免循环引用造成的引用计数无法归0,然后内存泄漏——考虑一个view的delegate为该view所在controller的情况。)
2.retain: 释放旧的对象 将旧对象的值赋予输入对象 并将输入对象的索引计数+1 ,主要应用与NSObject与其子类中.具体实现如下:Book类创建一个对象
- (void)setBook:(Book *)book{
if (_book != book) {
[_bookrelease]; // 释放掉旧的_book不用担心开始_book = nil时候,释放 [nil release]在OC中不算错误没有空指针概念
_book = [bookretain]; // book赋值给新的_book
}
}
- (Book*)book{
return _book;
}
3.copy:这个会自动生成你赋值对象的克隆,相当于在内存中新生成了该对象的副本,这样一来,改变赋值对象就不会改变你声明的这个成员变量了(这个会在接下来的Copy)细说, 一般------>推荐做法是NSString类型用copy4.nonatomic和atomic:atomic即原子的意思,在多线程的程序中,atomic的数据成员在读写时会加锁,,保证数据的安全。nonatomic则认为该数据成员不会同时被多线程读写,如果 该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。推荐做法是开发iPone应用一般用nonatomic或者基本上所有用property的地方
5.readonly: 表示只读属性 只会生成getter方法 不会生成setter方法
6.readwrite:设置可供访问的级别,可读写,默认设置
@再来介绍一下property和synthesize:
@property (nonatomic) Book* book; @synthesize book = _book
1.这里一点:如果你的XCode版本较高,引入了ARC机制,就不需要在这里做retain,系统会自动帮你管理,但并不是JAVA的那种垃圾回收机制,OC还是要释放内存,不过是编译器会自动在合适的位置加入retain和release操作
2.@property会自动帮你生成对象的getter方法和setter方法.setter方法以“set”开头,后接属性名,属性名第一个字母变为大写:如book的setter方法为setBook.getter方法和属性使用相同的名字为book.而且合成的对象变量名和属性值相似,只是前面加了“_”前缀,如:_book。
3.如果你调用了@synthesize而没有指定名字,则对象变量名会和你的属性名相同,没有“_”。即,如果你只是@synthesize book 那生成的变量名就是book而不是_book.*在Xcode4.5及以后的版本中,可以省略@synthesize ,编译器会自动帮你加上getter 和 setter 方法的实现,并且默认会去访问_book这个成员变量,如果找不到_book这个成员变量,会自动生成一个叫做 _book的私有成员变量。如果你想让你的子类用到父类的属性,那么你还要在.h文件中进行声明,因为声明默认的是protect性质,Book *_book;
4.//代码一:
@synthesize name = _name; //这句话,编译器发现你没有定义任何getter和setter,所以会同时会你生成getter和setter
//代码二:
@synthesize name = _name; //因为你定义了name,也就是getter方法,所以编译器只会为生成setter方法,也就是setName方法。
-(NSString*) name{
NSLog(@"name");
return _name;
}
//代码三:
@synthesize name = _name; //这里因为你定义了setter方法,所以编译器只会为你生成getter方法
-(void) setName:(NSString *)name{
NSLog(@"setName");
if (_name != name) {
[_name release];
_name = [name copy];
}
}
//代码四:
@synthesize name = _name; //这里你自己定义了getter和setter,这句话没用了,你可以注释掉。
-(NSString*) name{ // 一般,当我们想对定义的变量有所操作的时候,才会自己定义getter和setter,因为@property生成的getter和setter格式是固定的
NSLog(@"name"); // 假设我定义了一个price价格,我想把它增加99倍,这里就需要重写getter和setter方法,_price = _price * 100
return _name;
}
-(void) setName:(NSString *)name{
NSLog(@"setName");
if (_name != name) {
[_name release];
_name = [name copy];
}
}
44