2011-09-27 31 views
0

UIImage API參考文檔: -
initWithContentsOfFile:
初始化並返回圖像對象與指定文件的內容。iOS - 我很困惑這裏如何處理內存?

- (id)initWithContentsOfFile:(NSString *)path 

參數
路徑
到文件的路徑。該路徑應包含用於標識圖像數據類型的文件擴展名。
返回值 的初始化UIImage對象,或如果該方法無法找到文件或從它的內容初始化圖像。


考慮到這種情況,假設我有一個類,它可以是任何類的擴展。例如,剛剛拿UIImage。

@interface myImage : UIImage 
{ 
    BOOL isDefaultSet; 
} 

-(id)initWithDefaultImage; 

@end 

@implementation myImage 


-(id)initWithDefaultImage 
{ 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"]; 

    idDefaultSet = YES; 

    return [self initWithContentsOfFile:path]; 
} 

@end 


//somewhere in other class: 

NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"]; 

myImage *myObject = [[myImage alloc] initWithDefaultImage]; 
UIImage *yourObject = [[UIImage alloc] initWithContentsOfFile:path]; 

現在這裏在兩種情況下,

「黃金」 給 「retainCount + 1」

如果

initWithDefaultImage/initWithContentsOfFile

返回無因一些問題 - 讓我們說(無效的文件路徑),作爲

myObject的/ yourObject

將被設置爲無,即使分配是以前初始化使這個內存會被泄露。

我以這種方式看到了擴展類/接口的許多實現。我很困惑如何處理內存?任何人都可以分享對此的看法?

+0

我建議遵守約定,讓你的類以大寫字母開頭。你會讓你的生活更輕鬆(如果你和其他人一起工作,你將避免被侮辱和毆打;-) – DarkDust

+0

親愛的DarkDust ..我只是在討論這個問題。請不要這麼苛刻..! – samfisher

+0

我認爲DarkDust正在開玩笑,就這些。然而,DarkDust是正確的,因爲我已經學會了艱難的方式,即類應該大寫,ivars和方法以小寫開頭。 – johnbakers

回答

1

如果[super init]返回nil,則返回nil。所以從方法控制返回,如果(someInitializingFailed)塊絕不會叫「initWithFoo」

如果[super init]回報nil,超強的init已經後自己清理之前被執行,並且內存將作爲頁頭已經執行,被泄露和釋放了由alloc分配的內存。

Handling Initialization Failure

您應該只在故障點呼籲自我釋放方法。如果您從調用超類的初始值設定項中返回零,您不應該也調用release。

0

你是對的,有時候人們會忘記處理這個泄漏。如果我們無法繼續進行初始化,則需要釋放分配的內存。

-(id)initWithDefaultImage 
{ 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"]; 
    if (path != nil) 
    { 
     self = [super initWithContentsOfFile:path]; 
    } 
    else // cannot proceed with init 
    { 
     [self release]; 
     self = nil; 
    } 
    return self; 
} 
+0

如何在初始化完成init之後調用initWithContentsOfFile? – samfisher

+0

好點。我已經更新了代碼。 – Davyd

1

通常情況下,相應的初始版本self(新目標)返回nil,如前:

- (id)initWithFoo 
{ 
    self = [super init]; 
    if (!self) return nil; 

    if (someInitializingFailed) { 
     [self release]; 
     return nil; 
    } 

    return self; 
} 

你可以假設-[UIImage initWithContentsOfFile:]正在實施同樣的模式。所以除非儀器確實告訴你有泄漏,否則你不需要在你的情況下做任何特殊處理。

+0

也看到這種情況。如果[super init]返回nil,則返回nil。所以控制從方法返回並且如果(someInitializingFailed)塊永遠不會被執行,並且在調用「initWithFoo」之前已經執行了alloc,內存將會泄漏。 – samfisher

+0

如果我替換 - > return [self initWithContentsOfFile:path];用 - > return [super initWithContentsOfFile:path];那麼它會是正確的? – samfisher

+2

@samfisher如果'[super init]'返回'nil',超級'init'已經清理完畢並釋放'alloc'分配的內存。 [換句話說](http://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Chapters/ocAllocInit.html#//apple_ref/doc/uid/TP30001163-CH22-SW13),「你只能在失敗點調用release方法,如果你從調用超類的初始化方法返回零,你也不應該調用release。「 – albertamg