面試中刑枝,往往屬性的幾大修飾符被問到的概率非常的大,所以我就做了點試驗惧辈,總結(jié)一下
接下來先列舉一下 我在實驗過程當中學(xué)到的一些知識點
引用計數(shù)機制只使用在堆中, 所有不保存在堆中的數(shù)據(jù)的引用計數(shù)都為-1。
Autorelease Pool作用:緩存池,可以避免我們經(jīng)常寫relase的一種方式凑懂。其實就是延遲release,將創(chuàng)建的對象梧宫,添加到最近的autoreleasePool中接谨,等到autoreleasePool作用域結(jié)束的時候,會將里面所有的對象的引用計數(shù)減1塘匣。
系統(tǒng)類的對象方法和類方法的區(qū)別:類方法是系統(tǒng)自己創(chuàng)建對象脓豪,然后返回的對象的指針,在指向我們自定義的變量忌卤; 對象方法是咱們自己創(chuàng)建一塊內(nèi)存區(qū)域扫夜,然后用一個指針去指向它; 所以往往驰徊,類方法的引用計數(shù)要比對象方法+1笤闯,MRC里面類方法還不用自己手動釋放;ARC下面的 所有變量都是加在自動釋放池里面的棍厂,所以不需要手動釋放;
ARC下,定義屬性之后,系統(tǒng)會實現(xiàn)set方法和get方法
參照MRC下的實現(xiàn)
setter:
- (void)setOneArr:(NSArray *)oneArr{
if (_oneArr != oneArr) {
[oneArr release];
_oneArr = [oneArr retain];//或者copy視情況而定 屬性的引用計數(shù)增加的原因就在這里
}
}
getter:
- (NSArray *)oneArr{
if (!_oneArr) {
_oneArr = @[@"1",@"2",@"3"];
}
return [[_oneArr retain] autorelease]; // 屬性的引用計數(shù)增加的原因就在這里
}
- 注意 獲取獲取對象的引用計數(shù)
NSLog(@"retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strStrong)));//不要用self.
- 字符串的類型
I. NSCFConstantString 類型的對象都是在棧區(qū)的 引用計數(shù)一直都是 -1
NSString *str = @"xxxxxx";
NSString *str = [NSString stringWithString:@"xxxxxx"];
NSString *str = [[NSString alloc] initWithString:@"xxxxxx"];
NSString *str = [NSString string];
NSString *str = [[NSString alloc] init];
用上面幾種方式創(chuàng)建的都是 第一種類型的
II. NSTaggedPointerString 對象都是在棧區(qū)的 引用計數(shù)一直都是 -1
//不包含非ASCII字符并且不超過10個字符
NSString *str = [NSString stringWithFormat:@"%@",@"xxxxxx"];
NSString *str = [[NSString alloc] initWithFormat:@"%@",@"xxxxxx"];
NSString *str = [[NSString alloc] initWithUTF8String:"xxxxxx"];
NSString *str = [NSString stringWithUTF8String:"xxxxxx"];
III. CFString 引用計數(shù)正常
像大部分的面試題答案一樣颗味,
1. 對不可變的字符串、數(shù)組牺弹、字典浦马,都建議用copy时呀,為啥呢的? 接下來列舉一下具體的情況
如果用將可變字符串賦給不可變字符串時
NSMutableString *str = [[NSMutableString alloc] init];
1. Strong修飾的屬性 => self.strStrong = str;
[str appendString:@"xxxx"];
=> 臨時變量改變了的 self.strStrong也變了 則會影響原來值的純潔性
2. Assign修飾的屬性 => self.strAssign = str;
[str appendString:@"xxxx"];
=> 臨時變量改變了的晶默,self.strAssign也變了退唠,則會影響原來值的純潔性,而且一旦出了
作用域荤胁,由于assign對內(nèi)存是弱引用瞧预,導(dǎo)致內(nèi)存會提前釋放,但是assin修飾的指針卻一直存在仅政,
會造成野指針垢油,調(diào)用即會奔潰。
3. Copy修飾的屬性 => self.strCopy = str;
[str appendString:@"xxxx"];
=> 臨時變量改變了的 self.strCopy不受影響 推薦使用
4. Weak修飾的屬性 => self.strWeak = str;
[str appendString:@"xxxx"];
=> 臨時變量改變了的圆丹,self.strWeak也變了滩愁,則會影響原來值的純潔性,而且一旦出了作用域辫封,
由于Weak對內(nèi)存是弱引用硝枉,導(dǎo)致內(nèi)存會提前釋放,但是Weak修飾的指針會把指針置為nil倦微,
所以不會造成野指針妻味。
2. 對可變的字符串、數(shù)組欣福、字典责球,都建議用Strong,為啥呢的拓劝? 接下來列舉一下具體的情況
1.首先用了assign雏逾,會造成野指針,這和上面一樣;
2.用weak也一樣郑临,會提前釋放栖博;
3.Copy修飾的屬性,
NSMutableString *strx = [NSMutableString stringWithFormat:@"xxx??"];
self.mStrCopy = strx;
[strx appendString:@"xxx"];
//Attempt to mutate immutable object with appendString:
[self.mStrCopy appendString:@"xxx"];
首先厢洞,因為是copy修飾的仇让,所以在set方法里面,copy完得到的是不可變字符串犀变,所以進行字符串操作的時候會崩潰妹孙。
3. 對基礎(chǔ)數(shù)據(jù)類型,都建議用Assign获枝,為啥呢的蠢正?
assign 屬性修飾的話,是直接賦值的省店,如果對對象修飾的話嚣崭,沒有強引用笨触,創(chuàng)建完的內(nèi)存空間,立馬就會釋放雹舀,而assign修飾的指針卻沒有釋放芦劣,會造成野指針。
4. 用weak说榆,用來修飾代理虚吟,然后xib里面的連線一般都是weak,為啥呢的签财?
weak一般就是用來打破循環(huán)引用串慰。
weak為啥可以打破循環(huán)引用?
循環(huán)引用發(fā)生,對象之間的強引用唱蒸,導(dǎo)致內(nèi)存無法釋放邦鲫,就會導(dǎo)致內(nèi)存泄漏;weak的話神汹,指向并不會持有該對象庆捺,不會導(dǎo)致內(nèi)存無法釋放,就不會導(dǎo)致內(nèi)存泄漏屁魏。