API中是否保留了一些初始化方法的名称,如'initWithRequest'? 我有以下课程
@interface MTURLRequest : NSObject {
...
}
...
@end
和
@class MTURLRequest;
@protocol MTURLRequestHandlerDelegate;
@interface MTURLRequestHandler : NSObject {
...
}
-(id)initWithRequest:(MTURLRequest*)request_ delegate:(id<MTURLRequestHandlerDelegate>)delegate_;
@end
@protocol MTURLRequestHandlerDelegate<NSObject>
...
@end
我在调用初始值设定项的行中收到编译警告
-(void)enqueueRequest:(MTURLRequest*)request_ {
...
MTURLRequestHandler *handler = [[MTURLRequestHandler alloc] initWithRequest:request_ delegate:self];
...
}
警告:不兼容的Objective-C类型'struct MTURLRequest *',当从'initWithRequest:delegate:'传递参数1时,预期'struct NSURLRequest *'来自不同的Objective-C类型
代码中没有NSURLRequest。如果我将初始化程序重命名为initWithMTURLRequest,则所有内容都会编译而不会发出警告。用import语句替换MTURLRequest类的前向声明并没有改变任何东西。清理所有目标并重建。并且在范围内根本没有NSURLRequest * request_。
NSObject中没有'initWithRequest'初始值设定项。至少我找不到任何东西。 任何线索为什么会发生这种情况?
答案 0 :(得分:1)
完全重复。请参阅:Can't figure out 'warning: incompatible Objective-C types'
此评论表明您尚未找到Objective-C的基本设计点:
好的,谢谢。我刚刚重命名了 初始化。地狱,谁审查了 编译器并没有拒绝苹果 提交分发吗? :-) 一世 这样理解。可能没有 存在两个相同的选择器 一个应用程序,何时类型 他们的参数不同。
编译器的行为完全符合设计。 Objective-C在使用类型时非常简单且非常精确。基于类型的调度 - 由C ++和Java提供 - 虽然类型精确,但并不简单。
作为简单性的一部分,(id)
类型作为对任何类的对象(包括元类,技术上)的通用引用提供。将它与类型安全性和相同方法名称的多个声明相结合 - 相同的选择器 - 具有不同的参数会导致编译器正确识别的模糊性。
分离alloc和init 调用也可以是一个解决方案。 MTURLRequestHandler * requestHandler = [MTURLRequestHandler alloc]; [requestHandler initWithRequest:REQUEST_ 委托:自]
这不太正确。 -initWithRequest:delegate:
方法可以自由返回不同的对象。因此,您需要这样做:
MTURLRequestHandler *requestHandler = [MTURLRequestHandler alloc];
requestHandler = [requestHandler initWithRequest:....];
这非常不典型。转换+alloc
的返回值更为典型,但完全避免问题是建议的模式。
请注意,以上也是您应该始终将调用超级指定初始化程序的结果分配给self
的原因。