問題: NSArray和NSMutableArray在Copy和MutableCopy下的內(nèi)存是怎樣的港庄?深拷貝和淺拷貝的區(qū)別? 有兩種情況:淺拷貝和深拷貝。
淺拷貝只是復(fù)制了內(nèi)存地址,也就是對內(nèi)存空間的引用;
深拷貝是開辟新的空間并復(fù)制原空間相同的內(nèi)容灰伟,新指針指向新空間內(nèi)容。
除了NSArray在Copy下是淺復(fù)制儒旬,其他都是深復(fù)制栏账。
// 不可變數(shù)組
NSArray *oldArray = @[@1, @2, @3];
NSArray *newArray;
// 可變數(shù)組
NSMutableArray *oldMulArray = [[NSMutableArray alloc]initWithArray:oldArray];
NSMutableArray *newMulArray;
newArray = [oldArray copy]; // 淺拷貝
newArray = [oldArray mutableCopy]; // 深拷貝
newMulArray = [oldMulArray copy]; // 深拷貝
newMulArray = [oldMulArray mutableCopy]; // 深拷貝
問題: MRC中通過調(diào)用靜態(tài)方法創(chuàng)建的新對象,不再使用時需要對其發(fā)送release消息嗎义矛?
不需要发笔,因為約定靜態(tài)方法創(chuàng)建的對象會自動將其放入自動釋放池,即已對其發(fā)送autorelease消息凉翻,因此不可再對其進(jìn)行手動釋放了讨。MRC中靜態(tài)方法創(chuàng)建新對象的實現(xiàn)模板如下:
/** * 靜態(tài)構(gòu)造函數(shù) */
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age;
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age {
Person *person = [[[Person alloc] init] autorelease];
person.name = name;
person.age = age;
return person;
}
問題: BAD_ACCESS在什么情況下出現(xiàn)?
BAD_ACCESS報錯屬于內(nèi)存錯誤制轰,會導(dǎo)致程序崩潰前计,錯誤的原因是訪問了野指針(懸掛指針)。野指針指的是本來指針指向的對象已經(jīng)釋放了垃杖,但指向該對象的指針沒有置nil男杈,程序還以為該指針指向那個對象,導(dǎo)致存在一些潛在的危險訪問操作调俘,這些危險訪問操作就會導(dǎo)致BAD_ACCESS錯誤造成程序崩潰伶棒。訪問的含義包括多種情況,例如:向野指針發(fā)送消息彩库,讀寫野指針本來指向的對象的成員變量等等肤无。 ***
問題: 在block內(nèi)如何修改block外部變量?
在block內(nèi)部修改block外部變量會編譯不通過骇钦,提示變量缺少__block修飾宛渐,不可賦值。要想在block內(nèi)部修改block外部變量,則必須在外部定義變量時窥翩,前面加上__block修飾符:
/* block外部變量 */
__block int var1 = 0;
int var2 = 0;
/* 定義block */
void (^block)(void) = ^{
/* 試圖修改block外部變量 */
var1 = 100;
/* 編譯錯誤业岁,在block內(nèi)部不可對var2賦值 */
// var2 = 1;
};
/* 執(zhí)行block */
block();
NSLog(@"修改后的var1:%d",var1); // 修改后的var1:100
問題: 使用block時什么情況會發(fā)生引用循環(huán),如何解決寇蚊?
常見的使用block引起引用循環(huán)的情況為:在一個對象中強(qiáng)引用了一個block笔时,在該block中又強(qiáng)引用了該對象,此時就出現(xiàn)了該對象和該block的循環(huán)引用幔荒,例如:
/* Test.h */
#import <Foundation/Foundation.h> /* 聲明一個名為MYBlock的block糊闽,參數(shù)為空梳玫,返回值為void */
typedef void (^MYBlock)();
@interface Test : NSObject
/* 定義并強(qiáng)引用一個MYBlock */
@property (nonatomic, strong) MYBlock block;
/* 對象屬性 */
@property (nonatomic, copy) NSString *name;
- (void)print;
@end
/* Test.m */
#import "Test.h" @implementation Test
- (void)print {
self.block = ^{
NSLog(@"%@",self.name);
};
self.block();
}
@end
解決上面的引用循環(huán)的方法一個是強(qiáng)制將一方置nil爹梁,破壞引用循環(huán),另外一種方法是將對象使用__weak或者_(dá)_block修飾符修飾之后再在block中使用(注意是在ARC下):
- (void)print {
__weak typeof(self) weakSelf = self;
self.block = ^{
NSLog(@"%@",weakSelf.name);
};
self.block();
}
問題: 下面代碼有什么問題提澎?如何修改姚垃?
#import "TTAppDelegate.h"
@interface TTParent : NSObject
@property (atomic) NSMutableArray *children;
@end
@implementation TTParent
@end
@interface TTChild : NSObject
@property (atomic) TTParent *parent;
@end
@implementation TTChild
@end
@implementation TTAppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
TTParent *parent = [[TTParent alloc] init];
parent.children = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
TTChild *child = [[TTChild alloc] init];
child.parent = parent;
[parent.children addObject:child];
}
return YES;
}
@end
這是一個很明顯的“循環(huán)引用”問題,parent持有children數(shù)組盼忌,數(shù)組持有每一個child积糯,每個child又持有parent,這樣即使外部的所有引用都釋放了谦纱,由于這個引用循環(huán)看成,parent的引用計數(shù)將永遠(yuǎn)大于0永遠(yuǎn)無法被釋放。
解決方法很簡單跨嘉,將child對parent的引用改為weak弱引用即可川慌,這樣child對parent的弱引用不會導(dǎo)致parent的引用計數(shù)增加,且parent釋放后祠乃,weak修飾的對parent引用的指針會自動置nil梦重。
問題:僵尸對象、野指針亮瓷、空指針分別指什么琴拧,有什么區(qū)別?
僵尸對象:一個OC對象引用計數(shù)為0被釋放后就變成僵尸對象了嘱支,僵尸對象的內(nèi)存已經(jīng)被系統(tǒng)回收蚓胸,雖然可能該對象還存在,數(shù)據(jù)依然在內(nèi)存中除师,但僵尸對象已經(jīng)是不穩(wěn)定對象了沛膳,不可以再訪問或者使用,它的內(nèi)存是隨時可能被別的對象申請而占用的馍盟;
野指針:野指針出現(xiàn)的原因是指針沒有賦值于置,或者指針指向的對象已經(jīng)被釋放掉了,野指針指向一塊隨機(jī)的垃圾內(nèi)存,向他們發(fā)送消息會報EXC_BAD_ACCESS錯誤導(dǎo)致程序崩潰八毯;
空指針:空指針不同于野指針搓侄,它是一個沒有指向任何東西的指針,空指針是有效指針话速,值為nil讶踪、NULL、Nil或0等泊交,給空指針發(fā)送消息不會報錯乳讥,只是不響應(yīng)消息而已,應(yīng)該給野指針及時賦予零值變成有效的空指針廓俭,避免內(nèi)存報錯云石。 ***
問題: Objective-C有GC垃圾回收機(jī)制嗎?
GC(Garbage Collection)研乒,垃圾回收機(jī)制汹忠,簡單地說就是程序中及時處理廢棄不用的內(nèi)存對象的機(jī)制,防止內(nèi)存中廢棄對象堆積過多造成內(nèi)存泄漏雹熬。Objective-C語言本身是支持垃圾回收機(jī)制的宽菜,但有平臺局限性,僅限于Mac桌面系統(tǒng)開發(fā)中竿报,而在iPhone和iPad等蘋果移動終端設(shè)備中是不支持垃圾回收機(jī)制的铅乡。在移動設(shè)備開發(fā)中的內(nèi)存管理是采用MRC(Manual Reference Counting)以及iOS5以后的ARC(Automatic Reference Counting),本質(zhì)都是RC引用計數(shù)烈菌,通過引用計數(shù)的方式來管理內(nèi)存的分配與釋放阵幸,從而防止內(nèi)存泄漏。
另外引用計數(shù)RC和垃圾回收GC是有區(qū)別的僧界。垃圾回收是宏觀的侨嘀,對整體進(jìn)行內(nèi)存管理,雖然不同平臺垃圾回收機(jī)制有異捂襟,但基本原理都是一樣的:將所有對象看做一個集合咬腕,然后在GC循環(huán)中定時檢測活動對象和非活動對象,及時將用不到的非活動對象釋放掉來避免內(nèi)存泄漏葬荷,也就是說用不到的垃圾對象是交給GC來管理釋放的涨共,而無需開發(fā)者關(guān)心,典型的是Java中的垃圾回收機(jī)制宠漩;相比于GC举反,引用計數(shù)是局部性的,開發(fā)者要管理控制每個對象的引用計數(shù)扒吁,單個對象引用計數(shù)為0后會馬上被釋放掉火鼻。ARC自動引用計數(shù)則是一種改進(jìn),由編譯器幫助開發(fā)者自動管理控制引用計數(shù)(自動在合適的時機(jī)發(fā)送release和retain消息)。另外自動釋放池autorelease pool則像是一個局部的垃圾回收魁索,將部分垃圾對象集中釋放融撞,相對于單個釋放會有一定延遲。
相關(guān)問題: 自動釋放池跟GC(垃圾回收)有什么區(qū)別粗蔚?iPhone上有GC么尝偎?[pool release]和[pool drain]有什么區(qū)別?
[pool release]和[pool drain]在作用上是一樣的鹏控,都是傾倒自動釋放池致扯,區(qū)別是drain在支持GC垃圾回收的系統(tǒng)中(Mac系統(tǒng))可以引起GC回收操作,而release不可以当辐。對于自動釋放池一般還是使用[pool drain]了抖僵,一是它的功能對系統(tǒng)兼容性更強(qiáng),二者也是為了跟普通對象的release釋放區(qū)別開瀑构。自動釋放池的釋放操作指的是向池內(nèi)所有的對象發(fā)送release消息裆针,以讓系統(tǒng)及時釋放池內(nèi)的所有對象。 ***
問題: 如果一個對象釋放前被加到了NotificationCenter中寺晌,不在NotificationCenter中remove這個對象可能會出現(xiàn)什么問題?
首先對于NotificationCenter的使用澡刹,我們都知道呻征,只要添加對象到消息中心進(jìn)行通知注冊,之后就一定要對其remove進(jìn)行通知注銷罢浇。將對象添加到消息中心后陆赋,消息中心只是保存該對象的地址,消息中心到時候會根據(jù)地址發(fā)送通知給該對象嚷闭,但并沒有取得該對象的強(qiáng)引用攒岛,對象的引用計數(shù)不會加1。如果對象釋放后卻沒有從消息中心remove掉進(jìn)行通知注銷胞锰,也就是通知中心還保存著那個指針灾锯,而那個指針指的對象可能已經(jīng)被釋放銷毀了,那個指針就成為一個野指針嗅榕,當(dāng)通知發(fā)生時顺饮,會向這個野指針發(fā)送消息導(dǎo)致程序崩潰。 ***
問題: Objective-C是如何實現(xiàn)內(nèi)存管理的凌那?autorealease pool自動釋放池是什么兼雄?autorelease的對象是在什么時候被release的?autorelease和release有什么區(qū)別帽蝶?
Objective-C的內(nèi)存管理本質(zhì)上是通過引用計數(shù)實現(xiàn)的赦肋,每次RunLoop都會檢查對象的引用計數(shù),如果引用計數(shù)為0,說明該對象已經(jīng)沒人用了佃乘,可以對其進(jìn)行釋放了局蚀。其中引用計數(shù)可以大體分為三種:MRC(手動內(nèi)存計數(shù))、ARC(自動內(nèi)存計數(shù)恕稠,iOS5以后)和內(nèi)存池琅绅。
其中引用計數(shù)是如何操作的呢?不論哪種引用計數(shù)方式鹅巍,本質(zhì)都是在合適的時機(jī)將對象的引用計數(shù)加1或者減1千扶。
這里簡單歸結(jié)一下:
使對象引用計數(shù)加1的常見操作有:alloc、copy骆捧、retain
使對象引用計數(shù)減1的常見操作有:release澎羞、autorealease
自動釋放池
自動釋放池釋放的時機(jī),也就是自動釋放池內(nèi)的所有對象是在什么時候釋放的敛苇,這里要提到程序的運(yùn)行周期RunLoop妆绞。對于每一個新的RunLoop,系統(tǒng)都會隱式的創(chuàng)建一個autorelease pool枫攀,RunLoop結(jié)束時自動釋放池便會進(jìn)行對象釋放操作括饶。 autorelease和release的區(qū)別主要是引用計數(shù)減一的時機(jī)不同,autorelease會在對象的使用真正結(jié)束的時候才做引用計數(shù)減1,而不是收到消息立馬釋放来涨。
retain图焰、release和autorelease的底層實現(xiàn)
最后通過了解這三者的較底層實現(xiàn)來理解它們的本質(zhì)區(qū)別:
-(id)retain {
/* 對象引用計數(shù)加1 */
NSIncrementExtraRefCount(self);
return self;
}
-(void)release {
/* 對象引用計數(shù)減1,之后如果引用計數(shù)為0則釋放 */
if(NSDecrementExtraRefCountWasZero(self)) {
NSDeallocateObject(self);
}
}
-(id)autorelease {
/* 添加對象到自動釋放池 */
[NSAutoreleasePool addObject:self];
return self;
}
問題: 為什么很多內(nèi)置的類蹦掐,如TableViewController的delegate的屬性是assign不是retain?
delegate代理的屬性通常設(shè)置為assign或者weak是為了避免循環(huán)引用技羔,所有的引用計數(shù)系統(tǒng),都存在循環(huán)引用的問題卧抗,但也有個別特殊情況藤滥,個別類的代理例如CAAnimation的delegate就是使用strong強(qiáng)引用。
其他問法: 委托的property聲明用什么屬性社裆?為什么拙绊? * **問題: CAAnimation的delegate代理是強(qiáng)引用還是弱引用?
CAAnimation的代理是強(qiáng)引用浦马,是內(nèi)存管理中的其中一個罕見的特例时呀。我們知道為了避免循環(huán)引用問題,delegate代理一般都使用weak修飾表示弱引用的晶默,而CAAnimation動畫是異步的谨娜,如果動畫的代理是弱應(yīng)用不是強(qiáng)應(yīng)用的話,會導(dǎo)致其隨時都可能被釋放掉磺陡。在使用動畫時要注意采取措施避免循環(huán)引用趴梢,例如及時在視圖移除之前的合適時機(jī)移除動畫漠畜。
CAAnimation的代理定義如下,明確說了動畫的代理在動畫對象整個生命周期間是被強(qiáng)引用的坞靶,默認(rèn)為nil憔狞。
/* The delegate of the animation. This object is retained for the * lifetime of the animation object. Defaults to nil. See below for the * supported delegate methods. */
@property(nullable, strong) id <CAAnimationDelegate> delegate;
問題: OC中,與alloc語義相反的方法是dealloc還是release彰阴?與retain語義相反的方法是dealloc還是release瘾敢?需要與alloc配對使用的方法是dealloc還是release,為什么尿这?
alloc與dealloc語意相反簇抵,alloc是創(chuàng)建變量,dealloc是釋放變量射众;
retain與release語義相反碟摆,retain保留一個對象,調(diào)用后使變量的引用計數(shù)加1叨橱,而release釋放一個對象典蜕,調(diào)用后使變量的引用計數(shù)減1。
雖然alloc對應(yīng)dealloc罗洗,retain對應(yīng)release愉舔,但是與alloc配對使用的方法是release,而不是dealloc栖博。為什么呢屑宠?這要從他們的實際效果來看。事實上alloc和release配對使用只是表象仇让,本質(zhì)上其實還是retain和release的配對使用。alloc用來創(chuàng)建對象躺翻,剛創(chuàng)建的對象默認(rèn)引用計數(shù)為1丧叽,相當(dāng)于調(diào)用alloc創(chuàng)建對象過程中同時會調(diào)用一次retain使對象引用計數(shù)加1,自然要有對應(yīng)的release的一次調(diào)用公你,使對象在不用時能夠被釋放掉防止內(nèi)存泄漏踊淳。
此外,dealloc是在對象引用計數(shù)為0以后系統(tǒng)自動調(diào)用的陕靠,dealloc沒有使對象引用計數(shù)減1的作用迂尝,只是在對象引用計數(shù)為0后被系統(tǒng)調(diào)用進(jìn)行內(nèi)存回收的收尾工作。
問題: 以下每行代碼執(zhí)行后剪芥,person對象的retain count分別是多少
Person *person = [[Person alloc] init];
[person retain];
[person release];
[person release];
1-2-1-0垄开。開始alloc創(chuàng)建對象并持有對象,初始引用計數(shù)為1税肪,retain一次引用計數(shù)加1變?yōu)?溉躲,之后release對象兩次榜田,引用計數(shù)減1兩次,先后變?yōu)?锻梳、0箭券。 ***
問題:執(zhí)行下面的代碼會發(fā)生什么后果? Ball *ball = [[[[Ball alloc] init] autorelease] autorelease];
\程序會因其而崩潰疑枯,因為對象被加入到自動釋放池兩次辩块,當(dāng)對象被移除時,自動釋放池將其釋放了不止一次荆永,其中第二次釋放必定導(dǎo)致崩潰废亭。
問題: 內(nèi)存管理的幾條原則是什么?按照默認(rèn)法則屁魏,哪些關(guān)鍵字生成的對象需要手動釋放滔以?哪些對象不需要手動釋放會自動進(jìn)入釋放池?在和property結(jié)合的時候怎樣有效的避免內(nèi)存泄露氓拼?
起初MRC中開發(fā)者要自己手動管理內(nèi)存你画,基本原則是:誰創(chuàng)建,誰釋放桃漾,誰引用坏匪,誰管理。其中創(chuàng)建主要始于關(guān)鍵詞new撬统、alloc和copy的使用适滓,創(chuàng)建并持有開始引用計數(shù)為1,如果引用要通過發(fā)送retain消息增加引用計數(shù)恋追,通過發(fā)送release消息減少引用計數(shù)凭迹,引用計數(shù)為0后對象會被系統(tǒng)清理釋放。現(xiàn)在有了ARC后編譯器會自動管理引用計數(shù)苦囱,開發(fā)者不再需要也不可以再手動顯示管理引用計數(shù)嗅绸。
當(dāng)使用new、alloc或copy方法創(chuàng)建一個對象時撕彤,該對象引用計數(shù)器為1鱼鸠。不再需要使用該對象時可以向其發(fā)送release或autorelease消息,在其使用完畢時被系統(tǒng)釋放羹铅。如果retain了某個對象蚀狰,需要對應(yīng)release或autorelease該對象,保持retain方法和release方法使用次數(shù)相等职员。
使用new麻蹋、alloc、copy關(guān)鍵字生成的對象和retain了的對象需要手動釋放廉邑。設(shè)置為autorelease的對象不需要手動釋放哥蔚,會直接進(jìn)入自動釋放池倒谷。
下面代碼的輸出依次為:
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[ary addObject:str];
NSLog(@"%@%d",str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@"%@%d",str,[str retainCount]);
[ary removeAllObjects];
NSLog(@"%@%d",str,[str retainCount]);
2,3糙箍,1
3渤愁,2,1(right)
1深夯,2抖格,3
2,1咕晋,3
此問題考查的是非MRC下引用計數(shù)的使用(只有在MRC下才可以通過retain和release關(guān)鍵字手動管理內(nèi)存對象雹拄,才可以向?qū)ο蟀l(fā)送retainCount消息獲取當(dāng)前引用計數(shù)的值),開始使用類方法stringWithFormat在堆上新創(chuàng)建了一個字符串對象str掌呜,str創(chuàng)建并持有該字符串對象默認(rèn)引用計數(shù)為1滓玖,之后retain使引用計數(shù)加1變?yōu)?,然后又動態(tài)添加到數(shù)組中且該過程同樣會讓其引用計數(shù)加1變?yōu)?(數(shù)組的add操作是添加對成員對象的強(qiáng)引用)质蕉,此時打印結(jié)果引用計數(shù)為3势篡;之后的三次操作使引用計數(shù)加1后又減2,變?yōu)?模暗,此時打印引用計數(shù)結(jié)果為2禁悠;最后數(shù)組清空成員對象,數(shù)組的remove操作會讓移除的對象引用計數(shù)減1兑宇,因此str的引用計數(shù)變?yōu)榱?碍侦,打印結(jié)果為1。因此先后引用計數(shù)的打印結(jié)果為:3隶糕,2瓷产,1。
這里要特別注意上面為何說stringWithFormat方法是在堆上創(chuàng)建的字符串對象枚驻,這里涉及到NSString的內(nèi)存管理惯豆,下面單獨(dú)對其進(jìn)行擴(kuò)展和分析征堪。 OC中常用的創(chuàng)建NSString字符串對象的方法主要有以下五種
/* 字面量直接創(chuàng)建 */
NSString *str1 = @"string";
/* 類方法創(chuàng)建
NSString *str2 = [NSString stringWithFormat:@"string"];
NSString *str3 = [NSString stringWithString:@"string"]; // 編譯器優(yōu)化后棄用,效果等同于str1的字面量創(chuàng)建方式 */
/* 實例方法創(chuàng)建 */
NSString *str4 = [[NSString alloc] initWithFormat:@"string"];
NSString *str5 = [[NSString alloc] initWithString:@"string"]; // 編譯器優(yōu)化后棄用系宜,效果等同于str1的字面量創(chuàng)建方式
開發(fā)中推薦的是前兩種str1和str2的創(chuàng)建方式灾常,分別用來創(chuàng)建不可變字符串和格式化字符串霎冯。最新的編譯器優(yōu)化后棄用了str3的stringWithString和str5的initWithString創(chuàng)建方式,現(xiàn)在這樣創(chuàng)建會報警告钞瀑,說這樣創(chuàng)建是多余的沈撞,因為實際效果和直接用字面量創(chuàng)建相同,也都是在常量內(nèi)存區(qū)創(chuàng)建一個不可變字符串雕什,由系統(tǒng)自動管理內(nèi)存和優(yōu)化內(nèi)存缠俺,他們創(chuàng)建后可以認(rèn)為已經(jīng)被autorelease了显晶。另外,此處由于字符串的內(nèi)容都是“string”壹士,使用str1磷雇、str3和str5創(chuàng)建的的字符串對象實際在常量內(nèi)存區(qū)只有一個備份,這是編譯器的優(yōu)化效果躏救,而str2和str4由于是在堆上創(chuàng)建因此各自有自己的備份唯笙。
此外最重要的是這五種方法創(chuàng)建的字符串對象所處的內(nèi)存類型,str1盒使、str3和str5都是創(chuàng)建的不可變字符串崩掘,是位于常量內(nèi)存區(qū)的,由系統(tǒng)管理內(nèi)存少办;stringWithFormat和initWithFormat創(chuàng)建的都是格式化的動態(tài)字符串對象苞慢,在堆上創(chuàng)建,需要手動管理內(nèi)存英妓。
相關(guān)問題:當(dāng)你用stringWithString來創(chuàng)建一個新NSString對象的時候挽放,你可以認(rèn)為:
這個新創(chuàng)建的字符串對象已經(jīng)被autorelease了(right)
這個新創(chuàng)建的字符串對象已經(jīng)被retain了
全都不對
這個新創(chuàng)建的字符串對象已經(jīng)被release了
問題:什么是安全釋放?
釋放掉不再使用的對象同時不會造成內(nèi)存泄漏或指針懸掛問題稱其為安全釋放鞋拟。 ***
問題: 這段代碼有什么問題,如何修改骂维?
for (int i = 0; i < someLargeNumber; i++) {
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@“%@”, string);
}
代碼通過循環(huán)短時間內(nèi)創(chuàng)建了大量的NSString對象,在默認(rèn)的自動釋放池釋放之前這些對象無法被立即釋放贺纲,會占用大量內(nèi)存航闺,造成內(nèi)存高峰以致內(nèi)存不足。
為了防止大量對象堆積應(yīng)該在循環(huán)內(nèi)手動添加自動釋放池猴誊,這樣在每一次循環(huán)結(jié)束潦刃,循環(huán)內(nèi)的自動釋放池都會被自動釋放及時騰出內(nèi)存,從而大大縮短了循環(huán)內(nèi)對象的生命周期懈叹,避免內(nèi)存占用高峰乖杠。
代碼改進(jìn)方法是在循環(huán)內(nèi)部嵌套一個自動釋放池:
for (int i = 0; i < 1000000; i++) {
@autoreleasepool {
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
}
}
相關(guān)問題: 這段代碼有什么問題?會不會造成內(nèi)存泄露(多線程)澄成?在內(nèi)存緊張的設(shè)備上做大循環(huán)時自動釋放池是寫在循環(huán)內(nèi)好還是循環(huán)外好胧洒?為什么?
for(int index = 0; index < 20; index++) {
NSString *tempStr = @”tempStr”;
NSLog(tempStr);
NSNumber *tempNumber = [NSNumber numberWithInt:2];
NSLog(tempNumber);
}