ITunesFinder示例中的警告(Apress - Learning Obj-C)

时间:2009-10-08 11:00:06

标签: objective-c cocoa

当我编译下面的代码时,我收到以下警告:不兼容的类型发送“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;
}

任何指针/智慧都会非常感激。

加里

1 个答案:

答案 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文档非常适合这个主题: