3

我已經把下面的小例子,其中的Xcode(4.5.2)靜態分析顯然沒有檢測到泄漏,爲了覈實一些意見我已經就這個靜態分析:Xcode靜態分析器不檢測泄漏?

#import <Foundation/Foundation.h> 

@interface Foo : NSObject { 
    NSArray *array; 
} 
@property (nonatomic, retain) NSArray *array; 
- (void)bar; 
@end 

@implementation Foo 
@synthesize array; 
- (void)bar 
{ 
    // Shouldn't the static analyzer flag this as a leak? 
    array = [[NSArray alloc] initWithObjects:@"hello", @"world", nil]; 
} 
@end 

int main(int argc, const char *argv[]) 
{ 
    @autoreleasepool { 
     Foo *foo = [[Foo alloc] init]; 

     [foo bar]; 
     [foo bar]; 
     [foo bar]; 

     [foo release]; 
    } 

    return 0; 
} 

如果我沒有弄錯,重複調用bar將泄漏NSArray個實例。 bar創建一個NSArray實例,其名稱暗示它不會有+1保留計數。先前分配給array實例變量的實例泄漏,因爲它永遠不會釋放。

然而,真正令我關心的是,我在某處讀到ARC基本上使用與靜態分析器相同的算法。這是否意味着這個代碼也會在ARC下泄漏?或者,即使沒有__strong限定符或相應的(strong)屬性,ARC是否默認將所有實例變量視爲強壯?

+1

是的,在ARC下,所有實例變量(和範圍內的局部變量)都被視爲強變量。 – Mario

回答

5

無弧:

它沒有檢測到泄漏,因爲陣列是一個實例variable.So不被認爲是泄漏到其分配到具有保留計數到1的對象,這是因爲實例變量數組仍然可以訪問並且有效。
即使您多次調用該方法,靜態分析器也不足以知道該數組指向一個保留變量。
靜態分析器只是幫助您知道何時以單一方法泄漏對象。
但試圖改變方法方式:

- (void)bar 
{ 
    // Shouldn't the static analyzer flag this as a leak? 
    NSArray* array2 = [[NSArray alloc] initWithObjects:@"hello", @"world", nil]; 
} 

將由靜態分析儀進行檢測。

關於ARC

弧這個代碼沒有泄漏,因爲當你說陣列=,這就像如果你:

  1. 釋放數組:
  2. 保留新創建的對象;
  3. 將其分配給實例變量。

所以我建議轉向ARC如果可以的話。

+0

我明白了,謝謝!所以我不能依靠靜態分析器來安全地檢測我的Cocoa代碼中的所有內存泄漏。更不用說核心基金會的東西... – tajmahal

+0

只是爲了簡單的泄漏;儀器也沒有檢測到泄漏,但我相信他們會稍後改進,現在我們只需要做一些額外的調試。 –

+1

不幸的是,在最常見的情況下,靜態檢測所有內存泄漏會減少暫停問題。 –

相關問題