这是我目前对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:
的方法,它将使用其参数来填充实例变量url
,blurb
和author
。我不知道我应该用这个init
做些什么。我应该抛出异常吗?我还有其他选择吗?
答案 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_ATTRIBUTE
或NSAssert()
,但如果您使用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。
在您的情况下,使用裸init
和initWithObject:
,第二个可能是D.I.因此,您可以覆盖init
以使用默认参数调用initWithObject:
:
- (id) init {
return [self initWithObject:[Object objectWithURL:[NSURL URLWithString:@"http://www.apple.com"]
blurb:@""
author:@""]];
}
这将导致一种虚拟对象,使用无用的数据正确初始化。 (在ARC之外,请务必观察默认参数的内存管理 - 您希望使用自动释放/无主对象。)
*有时候initWithCoder:
会有例外。
答案 4 :(得分:1)
如果您有任何不希望调用的方法,并且您不希望子类支持,则在Debug构建中抛出异常是完全合理的。