1.怎么用 copy 關(guān)鍵字?
用途:
NSString霎挟、NSArray、NSDictionary 等等經(jīng)常使用copy關(guān)鍵字,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString汤纸、NSMutableArray、NSMutableDictionary芹血;
block 也經(jīng)常使用 copy 關(guān)鍵字贮泞。
說(shuō)明:
block 使用 copy 是從 MRC 遺留下來(lái)的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).在 ARC 中寫不寫都行:對(duì)于 block 使用 copy 還是 strong 效果是一樣的,但寫上 copy 也無(wú)傷大雅幔烛,還能時(shí)刻提醒我們:編譯器自動(dòng)對(duì) block 進(jìn)行了 copy 操作啃擦。如果不寫 copy ,該類的調(diào)用者有可能會(huì)忘記或者根本不知道“編譯器會(huì)自動(dòng)對(duì) block 進(jìn)行了 copy 操作”饿悬,他們有可能會(huì)在調(diào)用之前自行拷貝屬性值令蛉。這種操作多余而低效。
2.系統(tǒng)對(duì)象的 copy 與 mutableCopy 方法
不管是集合類對(duì)象(NSArray狡恬、NSDictionary珠叔、NSSet ... 之類的對(duì)象)袱蚓,還是非集合類對(duì)象(NSString, NSNumber ... 之類的對(duì)象)蚓曼,接收到copy和mutableCopy消息時(shí),都遵循以下準(zhǔn)則:
copy 返回的是不可變對(duì)象(immutableObject)嗽桩;如果用copy返回值調(diào)用mutable對(duì)象的方法就會(huì)crash兔乞。
mutableCopy 返回的是可變對(duì)象(mutableObject)汇鞭。
一、非集合類對(duì)象的copy與mutableCopy
在非集合類對(duì)象中庸追,對(duì)不可變對(duì)象進(jìn)行copy操作霍骄,是指針復(fù)制,mutableCopy操作是內(nèi)容復(fù)制锚国;
對(duì)可變對(duì)象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制腕巡。用代碼簡(jiǎn)單表示如下:
NSString str = @"hello word!";
NSString strCopy = [str copy] // 指針復(fù)制,strCopy與str的地址一樣
NSMutableString *strMCopy = [str mutableCopy] // 內(nèi)容復(fù)制血筑,strMCopy與str的地址不一樣
NSMutableString mutableStr = [NSMutableString stringWithString: @"hello word!"];
NSString strCopy = [mutableStr copy] // 內(nèi)容復(fù)制
NSMutableString *strMCopy = [mutableStr mutableCopy] // 內(nèi)容復(fù)制
二绘沉、集合類對(duì)象的copy與mutableCopy (同上)
在集合類對(duì)象中,對(duì)不可變對(duì)象進(jìn)行copy操作豺总,是指針復(fù)制车伞,mutableCopy操作是內(nèi)容復(fù)制;
對(duì)可變對(duì)象進(jìn)行copy和mutableCopy都是內(nèi)容復(fù)制喻喳。但是:集合對(duì)象的內(nèi)容復(fù)制僅限于對(duì)象本身另玖,對(duì)集合內(nèi)的對(duì)象元素仍然是指針復(fù)制。(即單層內(nèi)容復(fù)制)
NSArray arr = @[@[@"a", @"b"], @[@"c", @"d"];
NSArray copyArr = [arr copy]; // 指針復(fù)制
NSMutableArray *mCopyArr = [arr mutableCopy]; //單層內(nèi)容復(fù)制
NSMutableArray array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray copyArr = [mutableArr copy]; // 單層內(nèi)容復(fù)制
NSMutableArray *mCopyArr = [mutableArr mutableCopy]; // 單層內(nèi)容復(fù)制
【總結(jié)一句話】:
只有對(duì)不可變對(duì)象進(jìn)行copy操作是指針復(fù)制(淺復(fù)制),其它情況都是內(nèi)容復(fù)制(深復(fù)制)谦去!
3.這個(gè)寫法會(huì)出什么問(wèn)題:@property (nonatomic, copy) NSMutableArray *arr;
問(wèn)題:添加,刪除,修改數(shù)組內(nèi)的元素的時(shí)候,程序會(huì)因?yàn)檎也坏綄?duì)應(yīng)的方法而崩潰慷丽。
//如:-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460
// copy后返回的是不可變對(duì)象(即 arr 是 NSArray 類型,NSArray 類型對(duì)象不能調(diào)用 NSMutableArray 類型對(duì)象的方法)
原因:是因?yàn)?copy 就是復(fù)制一個(gè)不可變 NSArray 的對(duì)象鳄哭,不能對(duì) NSArray 對(duì)象進(jìn)行添加/修改要糊。
4.@synthesize 和 @dynamic 分別有什么作用?
@property有兩個(gè)對(duì)應(yīng)的詞妆丘,一個(gè)是@synthesize(合成實(shí)例變量)锄俄,一個(gè)是@dynamic。
如果@synthesize和@dynamic都沒(méi)有寫勺拣,那么默認(rèn)的就是 @synthesize var = _var;
// 在類的實(shí)現(xiàn)代碼里通過(guò) @synthesize 語(yǔ)法可以來(lái)指定實(shí)例變量的名字奶赠。(@synthesize var = _newVar;)
@synthesize 的語(yǔ)義是如果你沒(méi)有手動(dòng)實(shí)現(xiàn)setter方法和getter方法,那么編譯器會(huì)自動(dòng)為你加上這兩個(gè)方法药有。
@dynamic 告訴編譯器毅戈,屬性的setter與getter方法由用戶自己實(shí)現(xiàn),不自動(dòng)生成(如塑猖,@dynamic var)竹祷。
5.Objective-C 如何對(duì)內(nèi)存管理的,說(shuō)說(shuō)你的看法和解決方法羊苟?
答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動(dòng)內(nèi)存計(jì)數(shù))塑陵、手動(dòng)內(nèi)存計(jì)數(shù)、內(nèi)存池蜡励。
1). 自動(dòng)內(nèi)存計(jì)數(shù)ARC:由Xcode自動(dòng)在App編譯階段令花,在代碼中添加內(nèi)存管理代碼。
2). 手動(dòng)內(nèi)存計(jì)數(shù)MRC:遵循內(nèi)存誰(shuí)申請(qǐng)凉倚、誰(shuí)釋放兼都;誰(shuí)添加,誰(shuí)釋放的原則稽寒。
3). 內(nèi)存釋放池Release Pool:把需要釋放的內(nèi)存統(tǒng)一放在一個(gè)池子中扮碧,當(dāng)池子被抽干后(drain),池子中所有的內(nèi)存空間也被自動(dòng)釋放掉杏糙。內(nèi)存池的釋放操作分為自動(dòng)和手動(dòng)慎王。自動(dòng)釋放受runloop機(jī)制影響。