2014-02-21 124 views
1

有人能告訴我爲什麼下面的代碼在ARC下泄漏內存?我用Instruments測試了它們,它顯示它們會導致內存泄漏,但我不知道如何修復它們?iOS:內存泄漏代碼

static inline NSString* cachePathForKey(NSString* directory, NSString* key) { 
    return [directory stringByAppendingPathComponent:key]; //leak 
} 

@property (nonatomic,strong) NSMutableData *postBody; 

    if (![self postBody]) { 
     [self setPostBody:[NSMutableData data]]; //leak 
    } 

另一個問題是:這些儀器顯示我 「所有堆分配」 和 「所有匿名VM直播字節。例如,如果一個應用程序佔用超過80M(例如),它會崩潰。那麼80M意味着全部堆分配兩者都

UPDATE:

正如下面我評論人提到,我現在工作的變化非ARC ASIHttpRequest電弧模式。泄漏來了。就拿ASIInputStream例如:

+ (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest { 
    ASIInputStream *theStream = [[self alloc] init]; //leak 42% 
    [theStream setRequest:theRequest]; 
    NSInputStream *is = [NSInputStream inputStreamWithData:data]; //leak 58% 
    [theStream setStream:is]; 
    return theStream; 
} 
+0

我似乎不是泄漏給我! – Merlevede

+0

它是如何告訴你它們會導致內存泄漏? –

+1

這是否在後臺線程中調用? – Pang

回答

0

這是一個在黑暗中拍攝,但在C函數,你可以試試這個

__attribute__((ns_returns_autoreleased)) 
static inline NSString* cachePathForKey(NSString* directory, NSString* key) { 
    return [directory stringByAppendingPathComponent:key]; //leak 
} 

參看Clang docs欲瞭解更多信息。你也可以嘗試擺脫static inline,看看是否有幫助。

+0

不,一切都不起作用。我現在對於泄漏來自哪裏感到非常困惑:( 我現在正在處理將非ARC ASIHttpRequest更改爲ARC模式,並且泄漏出現。以ASIInputStream爲例:' +(id)inputStreamWithData:(NSData *)data請求:(ASIHTTPRequest *)theRequest { \t ASIInputStream * theStream = [[自的alloc] INIT]; //泄漏42% \t [theStream了setRequest:theRequest]; NSInputStream *是= [NSInputStream inputStreamWithData:數據];//泄漏58% \t [theStream setStream:是]; \t回theStream; } ' –

+0

@ZhaoRocky我冒昧地把這些信息在更新到您上面的問題。 –

0

如果您將ARC和非ARC代碼混合在一起,那麼很難在沒有看到大圖的情況下給出建議。我不知道你的技能水平是什麼,但我會讓新手遠離嘗試這種混合。

我測試了一段代碼,將它放在一個新的空的 iOS應用程序中;看起來是這樣的:

enter image description here

這裏是我的完整的AppDelegate實現,它什麼也不做,但連續運行的cachePathForKey功能。

#import "AppDelegate.h" 

@implementation AppDelegate 

static inline NSString* cachePathForKey(NSString* directory, NSString* key) { 
    return [directory stringByAppendingPathComponent:key]; //leak 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    while (YES) { 
     @autoreleasepool { 
      NSString *s = cachePathForKey(@"/my/fake/dir", @"key"); 
     } 
    } 

    return YES; 
} 

@end 

我運行它的Xcode,產品>檔案,當儀器啓動後,我選擇內存>泄漏。它沒有發現問題。你可以嘗試從頭開始建立起來,看看你是否可以通過這種方式找到問題。

另一種技術是複製你的項目(或分支;我強烈建議版本控制,特別是git)。然後開始剝離代碼,直到找到仍然泄漏的最小代碼。然後,您可以在某處發佈該代碼; github很常見,或者作爲一個小塊 - 一個gist - 或作爲一個完整的Xcode項目。無論哪種方式,自上而下或自下而上,這是令人沮喪和費力的,就像一個困難的科學發現,或一個難以捉摸的警方調查。但是,通過頑強的決心解決這些問題是成爲軟件開發人員的重要組成部分。這裏有一個非常有幫助的社區。祝你好運。