在Objective-C中实现委托模式

时间:2009-01-18 20:25:15

标签: iphone objective-c delegates

我正在构建一个处理NSURLConnection请求的类。为了允许其他类使用这个类,我想允许主类在触发connectionDidFinishLoading时调用委托。

我查看过很多文档,但是我找不到任何可以提供任何明确示例的内容,而且我所拥有的代码由于某些原因没有调用委托。到目前为止我的代码是(代码没有相关删除):

接口:

@interface PDUrlHandler : NSObject {
id delegate;
}
- (void)searchForItemNamed:(NSString *)searchQuery;
@property (nonatomic, assign) id delegate;
@end
@interface NSObject (PDUrlHandlerDelegate) 
- (void)urlHandler:(PDUrlhandler*)urlHandler searchResultsFinishedLoading:(NSDictionary *)resultData;
@end

实现:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"Fininshed Loading...");
    resultData = [self parseJSON:jsonData];

    if(delegate && [delegate respondsToSelector:@selector(urlHandler:searchResultsFinishedLoading:)]) {
        NSLog(@"Delegating!");
        [delegate urlHandler:self searchResultsFinishedLoading:resultData];
    } else {
        NSLog(@"Not Delegating. I dont know why.");
    }   

}

另一个班级中的代表:

- (void)urlHandler:(PDUrlhandler*)urlHandler searchResultsFinishedLoading:(NSDictionary *)resultData;
{
    NSLog(@"Delegating!!!!");
}

6 个答案:

答案 0 :(得分:4)

我的第一个想法是你可能没有设置代表,但你有。除此之外,代码看起来正确。看不出有什么不对。您是否尝试在检查代理是否响应选择器的位置放置断点?可能是委托值没有保留并变为零。确保你的代表不是零并且具有正确的对象。

您还确定连接是异步的吗?同步连接不会调用connectionDidFinishLoading方法

答案 1 :(得分:3)

原来我忘了设置代表:

[currentHandler setDelegate:self];

需要追踪对PDUrlHandler进行初始调用的行。

答案 2 :(得分:3)

对于有兴趣看到这样一个例子的人来说,苹果样本应用程序NSURLCache在NSURLCacheConnection.m中围绕NSURLConnection实现了一个简单的委托

示例应用程序可通过Apple开发人员连接获得: http://developer.apple.com/iphone/library/samplecode/URLCache/index.html

我发现它很有用。

答案 3 :(得分:1)

你走在正确的轨道上,你实现委托模式的方式看起来还不错。它没有被调用的原因是因为你在respondsToSelector中使用了错误的方法签名;当你真正想要humidorServer:searchResultsFinishedLoading:时,你有urlHandler:searchResultsFinishedLoading:

答案 4 :(得分:0)

它是委托中方法名称末尾的半冒号(最右边的底部代码示例)吗?如果设置了委托并且正在调用-connectionDidFinishLoading:方法,那么我看不出任何错误

答案 5 :(得分:0)

由于您使用“iphone”对其进行了标记,因此我假设您正在使用iPhone应用,并且不需要支持10.5之前的OS X.在Objective-C 2.0中,Apple建议您使用正式协议(使用@protocol)和可选方法而不是非正式协议。以下是相关文字:

  

非正式,协议声明   类别没有太多语言   支持。没有类型检查   编译时也不在运行时检查   看一个对象是否符合   协议。为了获得这些好处,你   必须使用正式的协议。一个   非正式协议可能有用   所有方法都是可选的,例如   对于代表,但(在Mac OS X v10.5上   以后)通常更好   使用带有可选的正式协议   方法

source