- @property 做了哪些事?
我们通常用@property来申明一个对象的属性,同时说明对象属性的内存管理,读写权限,getter,setter 方法名等。
当声明@property后在编译阶段编译器会自动生成该属性的setter, getter方法。如果没有指定
@property (nonatomic, strong, getter=”method” setter=”method”)
getter方法名就是该属性名称
setter方法则是set+首字母大写的属性名。
还会生成一个以下划线+属性名的实例变量。实例的名称我们还可以通过@synthesize语法来指定。
在@protocol 和 category 使用@property 并不会生成一个实例变量。
- 什么时候使用weak?
我们通常看到使用weak的场景:
// “非拥有关系” (nonowning relationship)
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
//必免循环引用
@property (nonatomic, weak) UIView *superView;
@property (nonatomic, weak) id<SomeDelegate> delegate;
对于IBoutLet 使用 weak我觉得是ViewController的view或者view的子类都已经持有IBoutlet对象了,Contoller就
不必要去管理view之间的事了,Controller只要能找到这个IBoutlet对象就行了,他们之间没有拥有关系。
assgin 一般用于非oc对象, weak 用于oc对象,但对于id类型的都可以用。
- copy的使用
NSString *string1 = @"dddd";
NSString *stringCopy = [string1 copy];
string1 = @"123456789"
NSMutableString *stringDCopy = [string mutableCopy];
NSLog(@"stringCopy = %@, stringDCopy = %@",stringCopy, stringDCopy);
(lldb) p string1
(__NSCFConstantString *) $0 = 0x0000000108dce2f0 @”dddd”
(lldb) p stringCopy
(__NSCFConstantString *) $1 = 0x0000000108dce2f0 @”dddd”
(lldb) p stringDCopy
(__NSCFString *) $2 = 0x00007ff6e173a330 @”123456789”
在集合类对象中,对immutable对象进行copy,是指针复制,mutableCopy是内容复制;对mutable对象进行copy和mutableCopy都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制
当把对象放入数组时,数组存数的是对象所指向的值的地址指针而不是该对象的指针
NSString *one = @"1";
NSString *two = @"2";
NSString *three = @"3";
NSArray *subArray = @[two, three];
NSArray *array = @[one,subArray];
two = @"4";
NSArray *copyArray = [array mutableCopy];
array = @[two,@[three, three]];
subArray = @[@"A", @"B"];
(lldb) p two
(__NSCFConstantString *) $2 = 0x00000001003432b0 @”2”
(lldb) p &two
(NSString **) $3 = 0x00007fff5f8c39e8
(lldb) p three
(__NSCFConstantString *) $4 = 0x00000001003432d0 @”3”
(lldb) p &three
(NSString **) $5 = 0x00007fff5f8c39e0
(lldb)
(lldb) p subArray[0]
(__NSCFConstantString *) $8 = 0x00000001003432b0 @”2”
(lldb) p subArray[1]
(__NSCFConstantString *) $9 = 0x00000001003432d0 @”3”
从上面我们可以得知,在subArray里面保存的是 two, three 所指向的值的地值而不是two,three 自己的地址,所以
当two或three的值发生变化时,subArray的值是不会变化的。
(lldb) p array
(__NSArrayI *) $14 = 0x00007f9299724640 @”2 objects”
(lldb) p copyArray
(__NSArrayM *) $15 = 0x00007f9299495250 @”2 objects”
(lldb) p array[0]
(__NSCFConstantString *) $16 = 0x0000000100343290 @”1”
(lldb) p copyArray[0]
(__NSCFConstantString *) $17 = 0x0000000100343290 @”1”
从上面我们可以看出, array 跟 copyArray的值地址完全不一样,所以这是一个值复制, 但他们里面的内容的地址却是一样的,
因为其内容是指针复制。
如果对象是不可变对象, 并且用copy方法那么一定是浅复制
如果对象是可变对象,无论copy,mutableCopy都是 深复制
如果是调用mutableCopy, 无论是可变对象还是不可变对象都是深复制。
用@property声明 NSString、NSArray、NSDictionary 经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
@property (nonatomic, strong) NSString *name;
NSMutableString *subName =[[NSMutableString alloc] initWithString:@"12345"];
self.name = subName;
NSLog(@"self.name = %@",self.name);
[subName appendString:@"qwert"];
NSLog(@"self.name = %@", self.name);
输出结果:
2015-09-17 17:16:51.296 Ego[48752:8992323] self.name = 12345
2015-09-17 17:16:51.297 Ego[48752:8992323] self.name = 12345qwert
当用strong修饰一个成员变量,并且成员变量的值是由一个可变对象赋给的,这时成员变量就可能因为别的地方修改了给其复制的变量而发生变化。如果我们需要的是一份单独的值,只需要设置为@property (nonatomic, copy) NSString *name;