18

我正在阅读 Mark Dalrymple在 Mac 上的 Learn Objective-C(仅在协议一章,所以仍然相对较新)并试图弄清楚:

为什么你会用自己的名字来引用一个类?如果我有一个名为 的课程Foo,我为什么要写,比如说,

[[Foo alloc] init]

并不是

[[[self class] alloc] init]

如果我有一个子类 Bar,第一个选项不会使我无法写作

[[Bar alloc] init]

而第二种选择会允许吗?什么时候第一个选项更好?

4

3 回答 3

28

通常,在类方法中,您确实使用[[self alloc] init]. 例如,为类编写便捷方法的规范方法是:

+ (id)fooWithBar:(Bar *)aBar
{
    return [[[self alloc] initWithBar:aBar] autorelease];
}

(注意,在类方法中,self指的是类对象。)

但是,如果您确实想要类的实例(而不是子类) ,则可以使用[[Foo alloc] init](即显式的类名)。Foo

于 2010-08-24T18:35:05.853 回答
7

每当您想要该类时,您都可以通过其名称来引用该类。如果子类是从该类派生的,则同一方法中的 self 将表示该派生类。因此,如果您想显式实例化超类,可以这样做。

在某些情况下,这可能是有意义的。要么强制子类覆盖该方法以返回其类的实例。或者返回一个不同的类,比如用于创建 NSArray 等的占位符对象。

于 2010-08-24T19:41:43.340 回答
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 ] 的定义冲突。在我将 [ self alloc ] 替换为 [ Block alloc ] 后,编译器错误消失了。这可能只是一个编译器无法消除歧义,即使上下文看起来足够清楚。

于 2015-10-02T21:21:50.683 回答