Why use [ClassName alloc] instead of [[self class] alloc]?

拥有回忆 提交于 2019-12-03 10:10:33

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).

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!