我有这段代码:
@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?
答案 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
在此文件中显示其声明。