如何处理无用的init?

时间:2011-10-31 21:53:39

标签: objective-c cocoa-touch coding-style object-initializers

这是我目前对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做些什么。我应该抛出异常吗?我还有其他选择吗?

5 个答案:

答案 0 :(得分: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,则需要某种-init的实现,即使它只返回nil }。

答案 1 :(得分:3)

您不必拥有简单的init - 您可以使用initWithObject:方法。如果您正在进行任何基本设置,这些设置在80%的时间内保持不变,或者如果您在所有初始值设定项中都有一些公共代码,则可以覆盖init,但不需要这样做。

另外,请考虑将您的initWithObject:名称更具体地更改为initWithPost:(我假设这是基于您的ivars的某种博客条目提取程序),所以更明显的是什么对象是理想的。

答案 2 :(得分: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];
}

答案 3 :(得分:3)

Apple为Cocoa编程建立的规则是每个类必须有一个初始化方法"Designated Initializer"。该类的每个其他初始化程序必须调用D.I. * 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:会有例外。

答案 4 :(得分:1)

如果您有任何不希望调用的方法,并且您不希望子类支持,则在Debug构建中抛出异常是完全合理的。