1

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

4

5 回答 5

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_ATTRIBUTEor NSAssert(),但如果您使用,则UNAVAILABLE_ATTRIBUTE需要某种实现-init,即使它只是返回nil

于 2011-10-31T22:00:01.763 回答
3

你不必有一个简单的init- 你可以简单地拥有你的initWithObject:方法。如果您正在执行任何基本设置,并且 80%​​ 的时间都保持不变,或者如果您在所有初始化程序中有一些通用代码,您可以覆盖init,但您不需要这样做。

还可以考虑将您的initWithObject:名称更改为更具体的名称,例如initWithPost:(我假设这是某种基于您的 ivars 的博客条目获取器),以便更清楚需要什么对象。

于 2011-10-31T21:55:58.387 回答
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];
}
于 2011-10-31T22:00:47.543 回答
3

Apple 为 Cocoa 编程建立的规则是每个类都必须有一个初始化方法,即“指定初始化方法”。类的每个其他初始化程序都必须调用该 DI* DI 本身必须调用超类的 DI 通常,具有最大参数数量的初始化程序(最完整地指定新对​​象的状态的初始化程序)是 DI

在您的情况下,使用裸init, 和initWithObject:,第二个可能是 DI 您将因此覆盖initinitWithObject:使用一些默认参数调用:

- (id) init {

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

这将产生一种虚拟对象,它使用无用的数据正确初始化。(在 ARC 之外,一定要注意默认参数的内存管理——你想使用自动释放/无主的对象。)

*有时会例外initWithCoder:

于 2011-11-01T02:47:50.993 回答
1

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

于 2011-10-31T22:36:43.243 回答