我正在阅读Mark Dalrymple的在Mac上学习Objective-C (仅在协议章节,所以仍然相对较新)并尝试解决问题:
为什么要用自己的名字引用一个类?如果我有一个名为Foo
的课程,我为什么要写,比方说
[[Foo alloc] init]
而不是
[[[self class] alloc] init]
如果我有一个子类Bar,那么第一个选项不会使我无法编写
[[Bar alloc] init]
而第二种选择会允许吗?第一种选择什么时候会更好?
答案 0 :(得分:26)
通常,在类方法中,您使用[[self alloc] init]
。例如,为类编写便捷方法的规范方法是:
+ (id)fooWithBar:(Bar *)aBar
{
return [[[self alloc] initWithBar:aBar] autorelease];
}
(注意,在类方法中,self
引用类对象。)
但是,如果您确实需要[[Foo alloc] init]
类的实例(而不是子类),则可以使用Foo
(即显式类名)。
答案 1 :(得分:6)
只要你想要那个类,你就可以用它的名字来引用一个类。如果子类是从该类派生的,则同一方法中的self将代表该派生类。因此,如果要显式实例化超类,可以这样做。
有时候这可能有意义。要么强制子类重写该方法,以便返回它的类的实例。或者返回一个不同的类,比如在创建NSArray等时使用的占位符对象。
答案 2 :(得分:0)
我发现[ClassName alloc]和[self alloc]不相等的条件。我列出它以防其他人面临类似的情况。
//Option 1
+ (NSInputStream *)streamWBlockWithArray:(NSArray *)dataArray
{ return [[[self alloc] initWithArray:dataArray] autorelease]; }
// Option 2
+ (NSInputStream *)streamBlockWithArray:(NSArray *)dataArray
{ return [[[Block alloc] initWithArray:dataArray] autorelease]; }
如果我使用选项1,编译器给出了重复定义的编译器错误,则initWithArray的定义被标记为与+ [NSArray initWithArray]中的定义冲突。用[block alloc]替换[self alloc]后,编译器错误消失了。这可能只是一个编译器无法消除歧义,即使上下文看起来足够清楚。