@property详解
属性:通过属性合成对象指定成员变量的setter和getter方法,简化代码,通过配置属性关键字可以实现具体的内存管理操作
//声明步骤:
ios5 之前:
1.先有声明成员变量,而且必须是要下划线的
2.声明属性
3.合成属性:@synthesize name = _name;
ios5 之后:
声明属性的同时,声明了其对应的成员变量(_name),自动 合成属性实现,推荐还是要写成员变量,苹果推荐这种书写格式
属性里面的参数:
第一类 内存管理相关
assign: 缺省值 修饰基本数据类型和delegate对象
retain: 对象类型
copy :对象类型(遵守<NSCopying>情况下)
第二类: 线程相关
atomic : 关心线程安全 通常用于多线程
nonatomic:不关心线程安全,通常用于单线程中
第三类
readwrite:读写
readonly:只读(只提供getter方法,不提供setter方法)
定义属性
//属性关键字 属性配置关键字 属性类型 属性名称
@property(nonatomic, retain, getter=getName) NSString *name;
@property(nonatomic, retain) NSString *code;
@property(nonatomic, assign, readonly) NSInteger age;
总结属性关键字
retain:对象使用,持有对象,引用计数+1
assign:默认属性,简单/复杂数据类型使用,直接赋值,不 做任何内存操作
nonatomic:非原子性,不保证变量的线程安全
atomic:默认属性,原子性,保证变量线程安全,会有性能开销
copy:对象不可变复制,常用于NSString,retain类似,持有对象
readonly:只读,只生成getter而不会生成setter。按照属性的含义,我们可以将只读属性理解为,只有取值方法的属性
它并非是完全不能设置属性的值,只是不能直接设置,多数情况下是通过设置其他关联属性来设置
getter = ...:定义getter方法的名称 ,如bool值
@property (nonatomic, assign, getter=isGood)BOOL good;
strong:强引用,ARC中使用strong,和retain功能相同
weak:弱引用,ARC中使用weak
属性关键字copy:
我们也会经常见到copy关键字,它的用法比较多样化。我们可以暂时这样理解,当它使用在不可变类型的属性时,等于strong;当它使用在可变类型时,每次赋值都会拷贝一个新的对象。
原理就是他的深复制,浅复制
该对象所在的类需遵守<NSCopying>,才可以使用copy
深复制:内容复制,编译器会开辟新的内存来存储复制对象的数据,复制对象retaincount默认为1,需要手动释放
浅赋值:指针赋值,只是将对象的引用计数加1,需要手动释放
copy:不可变复制,若对象是不可变的是浅复制,若对象是可变的,则是深复制,且复制对象不可变
mutableCopy:可变复制,无论对象可变/不可变都是深复制,复制的对象可变
NSString *string = [[NSString alloc] init];
NSString *string1 = [string copy];
NSLog(@"string = %p,string1 =%p",string,string1);
[string release];
[string1 release];
//指向地址相同:string = 0x7fff7cfebd00,string1 =0x7fff7cfebd00<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
NSArray *array1 = [[NSArray alloc]initWithObjects:@"1",@"2", nil];
NSArray *array2 = [array1 copy];
NSLog(@"%p,%p",array1,array2);
[array1 release];
[array2 release];
//指向地址相同:0x1003007f0,0x1003007f0
//结论:copy对于不可变对象,是指针复制,也叫浅复制
NSMutableString *mutableString =[[NSMutableString alloc] initWithFormat:@"%@",@"22"];
NSMutableString *mutableString1 =[mutableString copy];
NSLog(@"%p,%p",mutableString,mutableString1);
//地址不同:0x100300f40,0x323225
[mutableString release];
[mutableString1 release];
//copy对于可变对象,是内容复制,深复制,但复制过后的新地址中的内容为不可变
//同理可验证mutableCopy <NSMutableCopying>
//结论:对于可变和不可变对象,mutableCopy为深复制(开辟新内存,内容复制),且开辟的新内存中的内容为可变对象
//实践:
NSMutableArray * mArray =[@[@"123", @"456"] mutableCopy];
[mArray removeLastObject];
NSLog(@"array = %@", mArray);
[mArray release];