为什么使用[ClassName alloc]而不是[[self class] alloc]?

发布于 2024-09-16 00:09:33 字数 379 浏览 11 评论 0原文

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

为什么你会通过它来引用一个类自己的名字?如果我有一个名为 Foo 的类,那么我为什么要写,

[[Foo alloc] init]

而不是

[[[self class] alloc] init]

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

[[Bar alloc] init]

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

I'm reading through Mark Dalrymple's Learn Objective-C on the Mac (only at the chapter on Protocols, so still relatively newbish) and trying to figure something out:

Why would you ever reference a class by its own name? If I had a class called Foo, why would I ever want to write, say,

[[Foo alloc] init]

and not

[[[self class] alloc] init]

If I had a subclass Bar, wouldn't the first option invalidate me from writing

[[Bar alloc] init]

whereas the second option would allow it? When would the first option be better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沩ん囻菔务 2024-09-23 00:09:34

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

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

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

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

Generally, within a class method, you do use [[self alloc] init]. For example, the canonical way to write a convenience method for a class is:

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

(Note that in a class method, self refers to the class object.)

However, you would use [[Foo alloc] init] (that is, an explicit class name) if you actually want an instance of the Foo class (and not a subclass).

手心的海 2024-09-23 00:09:34

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

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

You refer to a class by it's name whenever you want exactly that class. If a subclass was derived from that class, a self in the same method would represent that derived class instead. Hence, if you want to explicitly instantiate a superclass, this could be done.

There are occasions where this might make sense. Either to force the subclass to override the method in order to return an instance of it's class. Or to return a different class, like a placeholder object used in the creation of an NSArray etc.

一紙繁鸢 2024-09-23 00:09:34

我发现 [ 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 ] 后,编译器错误消失了。这可能只是编译器无法消除歧义,即使上下文看起来足够清楚。

I found a condition under which [ ClassName alloc ] and [ self alloc ] were not equivalent. I am listing it in case others are faced with a similar situation.

//Option 1 
+ (NSInputStream *)streamWBlockWithArray:(NSArray *)dataArray 
{ return [[[self alloc] initWithArray:dataArray] autorelease]; } 
// Option 2 
+ (NSInputStream *)streamBlockWithArray:(NSArray *)dataArray
{ return [[[Block alloc] initWithArray:dataArray] autorelease]; }

If I use option 1, the compiler was giving a compiler error of duplicate definitions the definition of initWithArray was being flagged as conflicting with the definition from + [ NSArray initWithArray ]. The compiler error went away after I replaced [ self alloc ] by [ Block alloc ]. This is probably just a compiler unable to disambiguate even though the context seems clear enough.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文