ARC是通過編譯器自動(dòng)加入Retain盒让、Copy和Release等方法調(diào)用來實(shí)現(xiàn)內(nèi)存管理搜锰,仍然以引用計(jì)數(shù)為基礎(chǔ)。
1. Strong和Copy的區(qū)別
依據(jù)ARC的實(shí)現(xiàn)原理身坐,屬性被Strong或Copy修飾決定在其Setter方法中調(diào)用Retain還是Copy秸脱。
//使用strong修飾的strongString屬性的Setter方法
- (void)setStrongString:(NSMutableString *)strongString
{
if (strongString != _strongString) {
[_strongString release];
_strongString = [strongString retain];
}
}
//使用copy修飾的copytoString屬性的Setter方法
- (void)setCopytoString:(NSMutableString *)copytoString
{
if (copytoString != _copytoString) {
[_copytoString release];
_copytoString = [copytoString copy];
}
}
2. Strong和Copy在什么情況下使用
(1) Strong
strong一般用于非容器類對(duì)象。會(huì)增加引用計(jì)數(shù)部蛇。相當(dāng)與Mrc中的Retain摊唇。
(2)Copy
copy用于容器類對(duì)象,比如NSString涯鲁、NSArray巷查、NSDictionary,或其他實(shí)現(xiàn)NSCopying抹腿、NSMutableCopying協(xié)議的對(duì)象岛请。對(duì)于Setter傳入對(duì)象為不可變對(duì)象時(shí),功能與strong相同警绩。對(duì)于Setter方法傳入對(duì)象為可變對(duì)象時(shí)崇败,會(huì)進(jìn)行深拷貝,不增加引用計(jì)數(shù)肩祥。
3. 測(cè)試實(shí)例和結(jié)果
//聲明兩個(gè)String類型的屬性后室,一個(gè)用strong修飾微渠,一個(gè)用copy修飾
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copytoString;
//賦值值類型為可變對(duì)象
- (void)test
{
NSMutableString *str = [NSMutableString stringWithFormat:@"123"];
NSLog(@"初始str = %@ p = %p &p = %p",str,str,&str);
self.copytoString = str;
self.strongString = str;
[str appendString:@"123"];
NSLog(@"拼接后str = %@ p = %p &p = %p",str,str,&str);
NSLog(@"copytoString = %@ p = %p class = %@",self.copytoString,_copytoString,NSStringFromClass([_copytoString class]));
NSLog(@"strongString = %@ p = %p class = %@",self.strongString,_strongString,NSStringFromClass([_strongString class]));
}
//可見copy生成了新的內(nèi)存空間,而strong沒有咧擂,修改了原對(duì)象值后逞盆,strong修飾的屬性值也變了。
str = 123 p = 0x60400044dcb0 &p = 0x7ffeeeb61ee8
str = 123123 p = 0x60400044dcb0 &p = 0x7ffeeeb61ee8
copytoString = 123 p = 0xa000000003332313 class = NSTaggedPointerString
strongString = 123123 p = 0x60400044dcb0 class = __NSCFString
給屬性賦值不可變類型值
- (void)test2
{
NSString *str = @"123";
NSLog(@"str = %@ p = %p &p = %p",str,str,&str);
self.copytoString = str;
self.strongString = str;
NSLog(@"copytoString = %@ p = %p class = %@",self.copytoString,_copytoString,NSStringFromClass([_copytoString class]));
NSLog(@"strongString = %@ p = %p class = %@",self.strongString,_strongString,NSStringFromClass([_strongString class]));
}
輸出結(jié)果
str = 123 p = 0x10eea1078 &p = 0x7ffee0d5dee8
copytoString = 123 p = 0x10eea1078 class = __NSCFConstantString
strongString = 123 p = 0x10eea1078 class = __NSCFConstantString
由測(cè)試可見松申,給屬性賦于值的對(duì)象類型為不可變類型時(shí)云芦,Strong和Copy效果一樣,淺拷貝贸桶,增加引用計(jì)數(shù)舅逸。賦值的對(duì)象類型為可變類型時(shí),Strong修飾的屬性會(huì)淺拷貝皇筛,增加引用計(jì)數(shù)琉历,Copy修飾的屬性會(huì)深拷貝,不增加引用計(jì)數(shù)水醋。
4. 相關(guān)知識(shí):深拷貝旗笔,淺拷貝
淺拷貝 淺拷貝就是復(fù)制指向?qū)ο蟮闹羔槨?br> retain、strong拄踪、不可變對(duì)象的copy都屬于淺拷貝蝇恶。
深拷貝 深拷貝就是拷貝對(duì)象本身。
可變對(duì)象的copy 和mutableCopy 是深拷貝惶桐。
而weak和unsafe_unretain應(yīng)該也屬于淺拷貝撮弧,不過不增加引用計(jì)數(shù)。最后這個(gè)是自己猜的姚糊。