2014-04-04 50 views
11

假装我对NSObject的类别定义以下方法:为什么dot语法不能用于返回类型为instancetype的方法?

+ (instancetype)allocTemplate 
{ 
    id instance = [self new]; 

    return instance; 
} 

,我有下面的类:

@interface FDActor : NSObject 

@property (nonatomic, copy) NSString *name; 

+ (void)sayHi;  

@end 


@implementation FDActor 

+ (void)sayHi 
{ 
    [self allocTemplate].name; 
} 

@end 

如何在编译时来[self allocTemplate].name错误了,如果自己是FDActor?

我知道它的作品,如果您使用正常的消息发送语法,但我明确感兴趣的点语法错误。

+0

什么是错误?我尝试了类似的东西,并将其编译。 –

+0

在'id'类型的对象上找不到属性'name'。只是要明确我并不是要用“FDActor”代替“自我”。我的意思是在FDActor内的类方法内调用该方法。 –

+0

如果该类别在NSObject上,那么不会将instancetype返回类型为NSObject的东西吗? – michaels

回答

3

它看起来好像instancetype仅用于分配期间的类型检查,所以 FDActor *actor = [FDActor allocTemplate]不会产生警告。

如果我们施放allocTemplate的返回类型,问题就会消失。

- (void)sayHi { ((__typeof__(self))[[self class] allocTemplate]).name; }

但要注意,因为将typeof在实例方法这只能一个实例是另一个实例。还要注意,因为我们现在明确地键入了返回值,所以allocTemplate方法不再是必需的,如果所有人都在寻找类型检查,那么我们甚至可以只投出零,它将工作。

如果我们尝试在一个类的方法同样的事情,这是行不通的

+ (void)sayHi { ((__typeof__(self) *)[self allocTemplate]).name; } 这是因为(__typeof__(self) *)实干家不能计算为FDActor *Class *这ARC会抱怨。看起来好像没有办法在编译时从类方法中以通用方式解析类型信息FDActor *

我宁可期待instancetype关键字稍微有用。

1

错误消息告诉你。 [self allocTemplate]id。属性语法从不适用于id

注意,这确实工作:

[FDActor allocTemplate].name; 

我认为类到instancetype是必须在调用中指定有关;否则我们只能回到id

+0

我明白这一点,但什么是那么instancetype呢? –

+0

http://nshipster.com/instancetype/ – matt

+1

对不起,我不是说我不知道​​什么样的实例类型。我的意思是,如果实例类型被视为所有方法的ID或针对它所调用的点语法属性,那么它的意义何在。实例类型的重点在于它被识别为称为方法的任何类的类型。我想要对方法调用进行类型检查,而不仅仅是分配。 –

0

我会对此进行一番尝试,但我并不完全理解instancetype支持是如何实现的,更不用说编译器类型检查系统的所有细节。换句话说,这是我最好的猜测,而不是一个权威的或完整的答案......

编译后,Objective-C方法实际上是函数,其中self是该函数的第一个参数,并键入id。所以,你必须:这里由+allocTemplate返回值的类型的

void sayHi(id self, SEL _cmd) 
{ 
    [self allocTemplate].name; // Actually calls to objc_msgSend, but that doesn't matter here 
} 

编译器的处理似乎与此有关。如果您将自己更改为明确的FDActor,则错误消失。当然,对于方法 - 与属性相反 - 编译器按照您的预期输入self,并且会警告(或者在ARC下出现错误)自我看起来不会响应的方法。看起来这可能是编译器检查instancetype上下文中可用方法与属性的区别(bug?)。

相关问题