1

这是目前我有我的init如何处理无用的init?

- (id)init 
{ 
    self = [super init]; 

    if (self) { 
     self.url = [[NSURL alloc] init]; 
     self.blurb = [[NSString alloc] init]; 
     self.author = [[NSString alloc] init]; 
    } 

    return self; 
} 

它做什么,但我有一个名为initWithObject:另一种方法,将使用它的参数来填充实例变量urlblurbauthor。我不知道我应该怎么做这个init。我应该抛出异常吗?我还有什么其他选择?

+0

您使用ARC吗? – hypercrypt

+0

我正在使用ARC。这对我的问题有影响吗? – john

+0

只有'self.url = [[NSURL alloc] init];'如果你不是这样的话会是内存泄漏(因为我相信你知道)。我以为你是,只是双重检查。 – hypercrypt

回答

11

如果你要替换自己的标准-init方法,你既可以返回nil(如果你不想-init不被使用)或做:

- (instancetype)init 
{ 
    return [self initWithObject:nil]; 
} 

如果要完全停止使用-init你可将其标记为不可用属性或使用NSAssert:

// .h 
// ... 

- (instancetype)init UNAVAILABLE_ATTRIBUTE; 

// ... 

// .m 
- (instancetype)init 
{ 
    NSAssert(NO, @"This method should not be used"); 
    return nil; 
} 

您可以使用UNAVAILABLE_ATTRIBUTENSAssert(),但如果你使用UNAVAILABLE_ATTRIBUTE您需要某种我的即使它只是返回nil,也可以使用-init

+0

我不确定这里更安全,返回'nil'将意味着我不会崩溃,但稍后它可能会引入一些细微的逻辑错误。我认为对我来说,我宁愿我的程序崩溃,以便解决错误,这很可能是程序员错误,而不是使用正确的指定初始化程序或其变体之一。 –

+1

查看我的更新回答 – hypercrypt

3

你不一定要有一个普通的init-你可以简单地使用你的initWithObject:方法。如果您正在进行80%的时间保持不变的基本设置,或者如果您在所有初始化程序中都有一些通用代码,则可以覆盖init,但不需要。

也考虑更改您的initWithObject:名称更具体,像initWithPost:(我假设这是某种基于您的ivars的博客条目提取器),所以它更明显是什么对象的期望。

3

我觉得你误解了你所读的内容。我不认为你会抛出异常。你可以;然而,泄漏记忆。如果你的initWithObject方法看起来像这样:

- (id)initWithObject:(id)obj { 
    if ((self = [self init])) { 
       self.url=[obj url]; 
       self.blurb=[obj blurb]; 
       self.author=[obj author]; 
    } 
    return self; 
} 

而且你会很好。如果你的对象是用-init实例化的,并且你使用了一个被赋值的变量,假设它是真实的,你可能会得到一个异常。所以在后续的方法中,一定要在使用它们之前检查对象是否存在。

如果用-init使你的对​​象,而不是-initWithObject这可能会抛出一个异常:

- (void)dealloc { 
     [url release]; 
     [blurb release]; 
     [author release]; 
     [super dealloc]; 
} 
1

如果你有你不想叫任何方法和你不希望你的子类为了支持,在Debug版本中引发异常是非常合理的。

3

规则,苹果已经为Cocoa编程确定的是,每类都必须有一个初始化方法这是"Designated Initializer"。每个其他的初始化程序都必须调用D.I. * D.I.本身必须称为超类的D.I.一般而言,参数的最大数(就是那个最完整地描述了新对象的状态)的初始化是直喷式

在你的情况下,与裸露的initinitWithObject:,第二个可能是D.I.因此,你会覆盖init调用initWithObject:一些默认参数:

- (id) init { 

    return [self initWithObject:[Object objectWithURL:[NSURL URLWithString:@"http://www.apple.com"] 
               blurb:@"" 
               author:@""]]; 
} 

这将导致一种虚拟的对象,这是正确的无用的数据初始化。 (在ARC以外,请务必观察缺省参数的内存管理 - 您想使用自动释放/无主物体。)

*有时会发生例外,如initWithCoder: