当我编译下面的代码时,我收到以下警告:不兼容的类型发送“ITunesFinder *”预期“id”?我只是刚开始并且说实话我对这个例子有点困惑。我有兴趣知道是否有办法在不使用委托类的情况下编写此示例?
我也对课程实施感到有些困惑,本书没有描述这是基于什么,或者说类别,协议或代表做什么,以及它们是如何工作的。
这是代码......
// INTERFACE
#import <Cocoa/Cocoa.h>
@interface ITunesFinder : NSObject
@end
// IMPLEMENTATION
#import "ITunesFinder.h"
@implementation ITunesFinder
-(void) netServiceBrowser: (NSNetServiceBrowser *) b
didFindService: (NSNetService *) service
moreComing: (BOOL) moreComing {
[service resolveWithTimeout:10];
NSLog(@"Service Found: %@", [service name]);
}
-(void) netServiceBrowser: (NSNetServiceBrowser *) b
didRemoveService: (NSNetService *) service
moreComing: (BOOL) moreComing {
[service resolveWithTimeout:10];
NSLog(@"Service Lost!: %@", [service name]);
}
@end
// MAIN
#import <Foundation/Foundation.h>
#import "ITunesFinder.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSNetServiceBrowser *browser = [[NSNetServiceBrowser alloc] init];
ITunesFinder *finder = [[ITunesFinder alloc] init];
NSLog(@"iTunesFinder ... Start");
[browser setDelegate: finder]; // <<< Warning here !!!!
[browser searchForServicesOfType: @"_daap._tcp" inDomain:@"local."];
NSLog(@"Browsing ...");
[[NSRunLoop currentRunLoop] run];
// Clean up
[browser release];
[finder release];
[pool drain];
return 0;
}
任何指针/智慧都会非常感激。
加里
答案 0 :(得分:4)
当我尝试使用gcc 4.2.1
在10.6下编译时,它编译时出现以下警告:
main.m:12: warning: class 'ITunesFinder' does not implement the 'NSNetServiceBrowserDelegate' protocol
我怀疑这是你描述的问题,但是来自编译器的更具描述性的诊断(可能是比你更新的版本?)。您可以通过将标头添加到标头中的接口声明来解决此警告:
@interface ITunesFinder : NSObject<NSNetServiceBrowserDelegate>
发出警告的原因是setDelegate:
方法具有以下签名:
- (void)setDelegate:(id <NSNetServiceBrowserDelegate>)delegate;
这意味着它可以使用任何实现正式NSNetServiceBrowserDelegate
协议的对象。由于您的类接口没有显式声明这一点,编译器会警告您这一事实。它应该仍然在运行时工作,只要在实际发送委托消息时提供实际方法。
是否可以在不使用委托类的情况下编写此示例?
不,委托类是接收事件通知的方式。
我也对课程实施感到有些困惑,本书没有描述这是基于什么,或者说类别,协议或代表做什么,以及它们是如何工作的。
NSNetServiceBrowserDelegate
协议定义了您的类需要实现的一组方法。你可以把它想象成Java中的接口或C ++中的虚拟基类。 Objective-C(不支持多重继承)的不同之处在于,您不从您尝试实现的接口继承,只是声明您的特定类根据协议实现这些方法。
现在协议用于各种各样的事情,Cocoa中一个非常常见的模式是将它们用于回调。所以在这里,您的ITunesFinder
正在实施浏览器协议,以便NSNetServiceBrowser
知道如何调用您的类(它以前从未见过!),以便提供浏览器通知。
这些委托通常用于将行为从框架类委托给您的某个类,以允许您轻松地自定义事物而无需大量子类,并接收事件通知(通常在有趣的事物之前和之后)。这是一个非常优雅的模型。
Apple文档非常适合这个主题: