在文件“Objective-C编程语言”苹果,第48页说:
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
一个是坏的,一个是好的,另一个是优秀的。 这是为什么?
还有第四种模式....
(1)类型不匹配是坏的。
(2)静态引用类的产率的方法,不会在子类中正确运行
(3)动态参照类意味着子类将被实例化作为子类的实例
(4)
+ (instancetype)rectangleOfColor:(NSColor *)color // Über-bestest evar!
{
Rectangle *newInstance = [[self alloc] init];
[newInstance setColor:color];
return newInstance;
}
LLVM添加instancetype
,说:“哟!这方法返回的任何类,它被称为上的一个实例”的关键字。 因此,如果你是子类上面,你可以:
RectangleSub *rs = [RectangleSub rectangleOfColor:[NSColor paisleyColor]];
但是,这会提醒(超出可怕的颜色选择):
RectangleSub *rs = [Rectangle rectangleOfColor:[NSColor puceColor]];
而(ID)的返回类型不会在第二种情况下发出警告。
请注意,我也切换声明newInstance
是明确的类型Rectangle*
。 这是越多越好,太多,在该方法的范围内 , newInstance
只能安全地处理过的Rectangle*
。
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
在类方法self
指类,而不是它的一个实例对象。
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
如果矩形将被继承(MyFancyRectangle),这仍然会返回一个普通的矩形对象,而
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
将返回MyFancyReactangle
好象叫喜欢MyFancyReactangle *r = [MyFancyReactangle rectangleOfColor:[UIColor redColor]]
为[self alloc]
被称为上sublass。 请注意,这里self
再次呼吁类,如+alloc
是一个类的方法。
出于同样的原因,所有init…
方便的创建者方法应该返回id
。 它允许子类没有编译器要疯了返回subclass'ed对象。
在第一种情况下,您指定self
指针(它应指向Rectangle
类对象)的实例Rectangle
。 这是绝对不正确。
在第二个,你硬代码的类实例化- Rectangle
在这种情况下。
第三,你让全班同学的身份,以确定类的实例,而不是在代码中显式指定它。 然后,如果你的Dodecahedron
类需要使用相同的代码,它不会需要改变类的名称。