1.关于@property
由于我们需要经常定义一些方法来访问成员变量,因此Objective-C提供了@property指令,来为我们自动生成setter和getter方法。
@property是编译器指令,在Xcode4.4之后,由@property修饰的成员变量会自动生成setter和getter方法的声明和实现。
不使用@property的情况下:
@interface Person : NSObject
{
@public
int _age;
int _number;
}
@end
@implementation Person
-(void)setAge:(int) age{
_age = age;
}
-(int)age{
return _age;
}
-(void)setNumber:(int) number{
_number = number;
}
-(int)number{
return _number;
}
@end
int main(int argc, const char * argv[]) {
Person *p = [Person new];
[p setAge:30];
NSLog(@"_number = %i, _age = %i", p->_number, p->_age);
return 0;
}
使用@property的情况:
@interface Person : NSObject
@property int age;
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
Person *p = [Person new];
[p setAge:30];
NSLog(@"_number = %i, _age = %i", p->_number, p->_age);
return 0;
}
现在:
用@property int age;就可以代替setter和getter方法的声明和实现
注意:
(1)默认情况下,由@property生成的setter和getter方法会访问以""开头的成员变量,如果没有“”开头的成员变量,会自动生成一个以“—”开头的成员变量,自动生成的成员变量是私有变量,只能在本来中访问,不能在其它类中访问。
(2)@property只会生成最简单的getter和setter方法,而不会进行数据的处理和过滤。如果需要对数据进行判断需要我们重写getter/setter方法:
若重写了setter方法,编译器就只会生成getter方法;
若重写了getter方法,编译器就只会生成setter方法;
若同时重写了setter和getter方法,编译器就不会自动生成不存在的变量。
(3)点语法实际上就是调用成员变量的setter和getter方法,如果点语法在“等号”左边,那么会调用成员变量的setter方法,如果点语法在“等号”右边,那么会调用成员变量的getter方法。
(4)如果给一个属性同时提供了getter/setter方法,那么我们称这个属性为可读可写属性;
如果只提供了getter方法,那么我们称这个属性为只读属性;
如果只提供了setter方法,那么我们称这个属性为只写属性;
2.@property修饰符
书写格式:
@property(属性修饰符) 数据类型 变量名称;
2.1权限访问修饰符
readonly:只读属性,只会生成getter方法,不会生成setter方法。
readwrite:可以生成setter/getter方法,可读可写属性
使用方法:
@property (readonly) int age;
2.2内存管理
assign,retain
weak,strong
这四个修饰符都是和内存管理相关的修饰符
retain和assign:
在之前的文章中我们说过,在MRC模式下,我们需要手动管理内存即手动对对象的引用计数器进行加1或减1.
例如,当进行多个对象的内存管理时,set方法需要使用
-(void)setRoom:(Room *)room{
if(_room != room){
[_room release]; //需要将之前的取值释放掉
}
[room retain]; //当person对象使用room对象时,要对room对象的引用计数器加1
_room = room;
}
为了方便我们开发,Objective-C为我们提供了retain修饰符
使用方法:
@property (retain) Room *room;
总结:因此,retain只能用来修饰对象,用retain修饰过的对象会自动生成内存管理的代码,且retain一般情况下都用在MRC模式下。
而assign刚好相反,assign只会生成普通的setter方法,并不会生成内存管理的代码
总结:assign不会生成内存管理的代码,不会增加引用计数,因此,assign既可以用来修饰基本类型(int float double NSInteger CGFloat,id等),也可以用来修饰对象类型。
weak和strong
在ARC(Automatical Reference Counting(自动引用计数))模式下,系统根据是否还有强指针指向当前对象判断是否释放当前对象。如果没有强指针指向当前对象,则系统会释放当前对象,如果没有强指针指向当前对象,则当前对象就会释放。
默认情况下,所有的指针都是强指针
例如:
{
Person *p = [[Person alloc] init];
}
//因为p是局部变量,所以当大括号结束时,p会被回收,p回收之后,就没有强指针指向当前对象了,所以,大括号结束的时候,Person实例对象也会被释放。
{
__strong Person *p = [[Person alloc] init];
__weak p2 = p;
p = nil; //在这一行的时候Person实例对象会释放
}
在ARC中进行多对象的内存管理时,需要使用strong修饰符修饰另一个对象。
@property (strong) Dog *dog;
weak修饰符和strong修饰符相对,是弱指针的意思。用弱指针指向的对象会自动释放。
2.3 copy(深拷贝和浅拷贝)