2011-09-27 65 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