最近在開發(fā)中遇到一個(gè)小bug,bug引起的原因是我在聲明一個(gè)屬性時(shí)對(duì)一個(gè)NSMutableString類型的數(shù)據(jù)使用了copy,但是賦值的是個(gè)NSString類型的值,接下來我調(diào)用了可變字符串的拼接方法。造成了崩潰。
@property (nonatomic, copy)NSMutableString *name;
接下來分析崩潰的原因。
在平時(shí)的開發(fā)中一般對(duì)于NSString這種常見的類型使用strong或者copy就行修飾,如無特別要求兩者皆可用。但畢竟是兩種不同的類型,還是有差異的:
- strong的情況下默認(rèn)生成的setter方法如下
-(void)setName:(NSString *)name{
_name = name;
}
- copy情況下生成的setter方法如下
- (void)setName:(NSString *)name{
_name = [name copy];
}
這時(shí)我在我的代碼中給name屬性賦值
NSMutableString *str = [NSMutableString stringWithFormat:@"bin"];
Dog *dog = [[Dog alloc] init];
dog.name = str;
在使用strong的情況下直接是把str賦值給了dog的name變量。此時(shí)如果我在別處改動(dòng)str將會(huì)造成dog的name隨之改變,因?yàn)樗麄冎赶蛲环輧?nèi)存。但是我如果使用的是copy,就會(huì)執(zhí)行copy特征的setter方法。此時(shí)dog的name變量獲取的僅僅是str進(jìn)行copy后的一個(gè)不可變副本。即使改動(dòng)了str也不會(huì)造成dog的name改變。相比這也是蘋果寫的所有屬性中字符產(chǎn)用copy的原因吧。但是如果賦值的數(shù)據(jù)str不是可變字符串這里strong和copy效果一樣。
還回到我的崩潰原因,由于我用的copy,所以不管你給我傳入的可變還是不可變,我接收到的肯定都是不可變的,但是我又在屬性處寫的NSMutableString。造成 一種我一定是可變字符串的假象,這時(shí)候如果我不小心調(diào)用了一些僅有不可變字符串才有的方法就會(huì)拋出異常。
所以建議如果是NSMutableString用strong,因?yàn)槿绻莝trong的話如果你傳入的值是NSString,直接Xcode會(huì)有個(gè)警告提醒你傳值有問題,早發(fā)現(xiàn)早治療。