LLVM编译器对实例类型的推导

时间:2013-10-30 12:19:40

标签: objective-c llvm

我有这段代码:

@interface Bar : UIView
- (id)initWithInt:(int)i;
@end

@implementation Bar
- (id)initWithInt:(int)i {
  self = [super init];
  return self;
}
@end

void func() {
  [[[Bar alloc] initWithInt:10] doSomething];
}

编译器在func()函数中给出了一个错误:Bar没有可见的@Interface声明选择器doSomething。 我的方法doSomething有另一个@interface。 编译器以某种方式假设initWithInt:返回instancetype而不是id。 对此有什么规定?在什么情况下编译器假定方法返回instancetype?

3 个答案:

答案 0 :(得分:4)

  

编译器在什么情况下假定方法返回   instancetype?

"CLANG LANGUAGE EXTENSIONS"中记录了这一点:

  

根据Cocoa惯例,具有某些名称的Objective-C方法   (“init”,“alloc”等)总是返回作为实例的对象   接收类的类型。据说这种方法具有“相关性”   结果类型“,意味着发送到这些方法之一的消息将   具有与接收器类的实例相同的静态类型。

     

...

     

确定方法是否具有推断的相关结果类型,即第一个单词   考虑camel-case选择器(例如,“initWithObjects”中的“init”),   如果返回类型为,则该方法将具有相关的结果类型   与其类的类型兼容,如果:

     
      
  • 第一个单词是“alloc”或“new”,方法是类方法,
  •   
  • 或第一个单词是“autorelease”,“init”,“retain”或“self”,和   该方法是一种实例方法。
  •   

因此,您的initWithInt:方法具有“推断的相关结果类型”,并且 因此,编译器假定它返回Bar的实例。

答案 1 :(得分:0)

不知道但是

inits总是应该返回实例类型。这是合乎逻辑的。我无法想象任何其他情况。

只需导入声明doSomething的子类,你就是好的

答案 2 :(得分:0)

  

我的方法doSomething确实有另一个@interface。

每个类必须只有一个@interface(尽管您可以进行类扩展,类别等以添加更多方法)。如果您的-doSomething方法属于另一个文件的类别(或类扩展名),请确保通过#import在此文件中显示其声明。