屬性修飾符:
MRC:
assign:基本數(shù)據(jù)類型(當(dāng)出現(xiàn)循環(huán)引用時(shí)骄酗,也要用assign)
retain:除Block和NSString外的其他對(duì)象
copy:一般用于NSString和Block
ARC:
strong:默認(rèn)
weak:多用于ui和解決循環(huán)引用
copy:用于NSString和Block
assign:非OC對(duì)象
既然NSString屬于OC對(duì)象,那么我們先不使用Copy修飾,在ARC模式下,聲明的屬性默認(rèn)是strong修飾,接下來就演示strong修飾NSString的后果
- 使strong修飾一個(gè)NSString對(duì)象
- 在viewDidLoad中實(shí)例化一個(gè)空的可變字符串
- 給可變字符串添加內(nèi)容
- 讓strong修飾的NSString對(duì)象指向可變字符串對(duì)象
- 繼續(xù)向可變字符串中添加內(nèi)容
- 打印strong修飾的NSString對(duì)象結(jié)果
#import "ViewController.h"
@interface ViewController ()
/* 為什么字符串使用copy修飾?
這里先不使用copy修飾,NSString是OC對(duì)象,并且是ARC模式,所以先使用strong來修飾演示
*/
@property (nonatomic,strong) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *str = [NSMutableString string];
[str appendString:@"xiaoming"];
self.name = str;
[str appendString:@"xiaogang"];
NSLog(@"%@",_name);
}
@end
結(jié)果為:
2016-07-31 13:51:35.218 字符串使用copy修飾[9376:241671] xiaomingxiaogang
結(jié)果分析:
如果使用strong修復(fù)NSString類型屬性
self.name 指向可變字符串對(duì)象的地址
當(dāng)可變字符串內(nèi)容發(fā)生變化時(shí),self.name相對(duì)應(yīng)的也發(fā)生變化
使用copy修飾后,將可變字符串重新拷貝一份,重新開辟內(nèi)存空間,修改mutableString的值,不會(huì)對(duì)self.name造成影響
2016-07-31 14:22:00.070 字符串使用copy修飾[9548:269772] str:0x7fa871488750,name:0xa006412031812da8
2016-07-31 14:22:00.074 字符串使用copy修飾[9548:269772] str:0x7fa871488750,name:0xa006412031812da8
2016-07-31 14:22:00.074 字符串使用copy修飾[9548:269772] xiaoming
剛剛的演示,我使用了NSMutableString(可變字符串),對(duì)mutableString執(zhí)行copy操作,屬于深拷貝,所以開辟的新內(nèi)存空間,如果使用的是NSString(不可變內(nèi)存),對(duì)NSString進(jìn)行copy屬于淺拷貝,不會(huì)開辟新的內(nèi)存空間,是不是就不會(huì)出現(xiàn)這個(gè)問題了呢?
接下來使用NSString來進(jìn)行演示,將屬性修飾符再次改回strong
#import "ViewController.h"
@interface ViewController ()
/* 為什么字符串使用copy修飾?
這里先不使用copy修飾,NSString是OC對(duì)象,并且是ARC模式,所以先使用strong來修飾演示
*/
@property (nonatomic,strong) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = [NSString string];
str = @"xiaoming";
self.name = str;
NSLog(@"str:%p,name:%p",str,_name);
str = @"xiaogang";
NSLog(@"str:%p,name:%p",str,_name);
NSLog(@"%@",_name);
}
@end
打印結(jié)果:
2016-07-31 14:17:19.127 字符串使用copy修飾[9499:264651] str:0x10c937060,name:0x10c937060
2016-07-31 14:17:19.128 字符串使用copy修飾[9499:264651] str:0x10c9370a0,name:0x10c937060
2016-07-31 14:17:19.128 字符串使用copy修飾[9499:264651] xiaoming
從結(jié)果上看,重新設(shè)置str的值后,self.name確實(shí)沒有受到影響
原因:
將之前的可變字符串變?yōu)椴豢勺冏址?因?yàn)镹SMutableString不支持append添加操作,我這里的兩次str賦值操作,其實(shí)是讓str重新指向了一片內(nèi)存空間,并不是修改了str原本內(nèi)存中的值
(OC中對(duì)象即指針,實(shí)際上存儲(chǔ)的是內(nèi)存地址,self.name = str; 實(shí)際是將str存儲(chǔ)的@"xiaoming"這塊地址給了self.name,self.name還指向著@"xiaoming")
所以改變str的指向后,self.name的指向并沒有改變,輸出沒有受到影響
結(jié)論
你只需要記住一點(diǎn),當(dāng)你給你的的NSString對(duì)象賦值時(shí),如果來源是NSMutableString,那么這種情況就必須要用copy;如果你確定來源是不可變類型的,比如@"http://www.reibang.com/users/691d9ed740cf/latest_articles"
這種固定的字符串,那么用strong比較好