文章目录
自动合成存取
@propery
- @propery 关键字是在编译阶段由编译器自动帮我们省称setter与getter方法。
@synthesize
-
当我们在实现文件中不写@synthesize properyName时在Xcode4.5之前的版本不会帮我们自动生成setter与getter方法,系统当然也不再会为我们生成对应的成员变量。在Xcode4.5之后的版本就可以不写@synthesize了。
-
当我们既定义了@synthesize,又在实现文件中人为重写setter和getter方法时,那么@synthesize将不再工作,也就不会为我们创建没有定义的_propertyName成员变量了,这时候如果在setter和getter方法中调用_propertyName将会发生编译错误。
@dynamic
- @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。
一.读写性控制
- readOnly 只读,只会生成getter方法,不会生成setter方法。
- readWrite 可读可写,会生成setter方法,也会生成getter方法。
二.setter相关修饰符
- assgin:表示直接复制,用于基本数据类型,包括id类型,这个修饰符不会牵涉到内存管理,但是如果是对象类型,使用此修饰符则可能会导致内存泄露。
- retain:针对对象类型进行内存管理,如果对基本数据类型使用,则X-code会直接报错,当给对象类型使用此修饰符时,setter方法会先将旧的对象属性release掉,在对新的对象进行一次赋值并进行一次retain操作 (会使引用计数+1)
- weak:打开ARC时才会使用,相当于assign,可以把对应的指针变量重置为空。
- strong:打开ARC时才会使用,相当于retain。
- copy:建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。
copy
- NSString、NSArray、 NSDictionary等等经常食用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、 NSMutableDictionary。为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份保护其封装性block,也经常使用copy,关键字block。
深浅拷贝
关键字 | 注释 |
---|---|
浅复制(shallow copy) | 在浅复制操作时,对于被复制对象的每一层都是指针复制 |
深复制(one-level-deep copy) | 在深复制操作时,对于被复制对象,至少有一层是深复制。 |
完全复制(real-deep copy) | 在完全复制操作时,对于被复制对象的每一层都是对象复制。 |
非集合类对象的 copy 与 mutableCopy
[不可变对象 copy] // 浅复制
[不可变对象 mutableCopy] //深复制
[可变对象 copy] //深复制
[可变对象 mutableCopy] //深复制
- 浅拷贝拷贝的是对象的地址(引用),而深拷贝拷贝的是对象的内容。
- 浅拷贝:创建一个新对象,并将原始对象的引用或指针复制给新对象,它们共享相同的数据。当原始对象或新对象的数据发生改变时,另一个对象也会受到影响。
- 深拷贝:指创建一个新对象,并将原始对象的内容复制到新对象中。这意味着新对象拥有自己的独立内存地址,与原始对象完全分离。当原始对象或新对象的数据发生改变时,彼此之间不会相互影响。
NSArray* arr1 = [NSArray arrayWithObjects:@"苹果", @"桃子", @"葡萄", nil];
NSArray* arr2 = [arr1 copy];
NSArray* arr3 = [arr1 mutableCopy];
NSLog(@"arr1 = %p, arr2 = %p, arr3 = %p", arr1, arr2, arr3); //每个元素的指针地址相同
如上图所示,arr1和arr2地址相同,但与arr3不相同。
因为arr1是不可变对象,arr2复制时使用copy关键字,进行了浅拷贝。
arr3复制时使用mutableCopy关键字,创建了一个新的对象,进行了深拷贝。
copy与strong关键字的区别
当我分别使用copy和strong关键字定义属性再进行复制时
@property (nonatomic, copy) NSArray* arr1;
@property (nonatomic, strong) NSArray* strongArr1;
NSMutableArray* test = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", nil];
self.arr1 = test;
self.strongArr1 = test;
NSLog(@"%p , %p",test, _arr1);
NSLog(@"%p , %p",test, _strongArr1);
可以看到,当我对test数组分别对copy和strong关键字定义的数组进行赋值时,
- 用copy关键字声明的arr1属性的地址发生了变化,也就是产生了一个新的对象,进行了深复制。
- 而用strong关键字声明的strongArr1属性的地址和test相同,进行了浅复制。
- strong修饰下,strongArr1会持有原来的对象,属于浅拷贝。
- 一般来说对于不可变对象我们使用copy修饰从而防止它的值发送改变,而可变的对象使用strong修饰。
三.原子性修饰符
- atomic:表示是线程安全的。
- nonatomic:表示是非线程安全的,使用此属性性能会提高一些。
(系统默认是atomic)