#import <Foundation/Foundation.h>
@interface Animals : NSObject
@property(nonatomic,strong) NSString *strongMonkey;
@property(nonatomic,copy) NSString *monkey;
@end
測試如下:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *defaultName = [NSMutableString stringWithFormat:@"猴子"];
Animals *animal = [Animals new];
animal.monkey = defaultName;//生成一份新的內存空間
animal.strongMonkey = defaultName;//指針指向同一塊內存空間
NSLog(@"%@,%@",animal.monkey,animal.strongMonkey);
[defaultName appendString:@"吃雞"];
NSLog(@"更改後:%@,%@",animal.monkey,animal.strongMonkey);
}
注:在strong情況下,如果外部被引用的變量更改了,那裏面這個值也會更改,因爲兩個屬性指向同一塊內存空間 。在這裏strong 屬於淺拷貝,只賦值對象的指針。爲了防止外界修改monkey,就用copy,因爲copy是生成了一份新的內存空間,所以外界是不能修改值。
打印結果:
猴子,猴子
更改後:猴子,猴子吃雞
strong ---- 這個屬性有可能指向一個可變對象,如果這個可變對象在外部被修改了,那麼會影響該屬性。
copy --- 經常用此特質來保護其封裝性。因爲傳遞給該屬性的新值有可能指向一個NSMutable類的實例,若是不拷貝,那麼設置完屬性之後,可變類實例的值就可能會在對象不知情的情況下遭人更改。
附:Block屬性聲明爲什麼用copy來修飾
首先,你必須要對(堆棧)有一定的理解。 block聲明後是放在棧裏的,只有copy後纔會放在堆上。當棧裏的block被釋放掉的時候,本地變量將變得不可訪問,一旦代碼執行到block這段就會導致崩潰。
ChangPhoneNumberController *vc = [[ChangPhoneNumberController alloc] init];
vc.changBackBlock = ^{
[self getUserinfo];
};
[self.navigationController pushViewController:vc animated:YES];
像這種block內部使用到的self當vc對象釋放掉的時候,引用到的self也會被釋放。而下面這種
__weak typeof(self) weakSelf = self;
_registView.registNextStepBlock = ^{
[weakSelf selectRegistSecond];
};
如果將改爲weakSelf改爲self 很可能會導致循環引用。self持有registView,registView持有registNextStepBlock,registNextStepBlock持有self。結果就是內存泄漏。