0

我有一个解析器类和一些视图控制器类。在解析器类中,我发送请求并接收异步响应。我想要多个下载,比如每个视图控制器一个。所以我在每个类中注册了一个观察者:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataDownloadComplete:) name:OP_DataComplete object:nil];

然后在中发布通知:

-(void)connectionDidFinishLoading:(NSURLConnection *)connection method of the parser class.
[[NSNotificationCenter defaultCenter] postNotificationName:OP_DataComplete object:nil];

但是在运行代码时,第一个视图控制器工作正常,但是在下载和解析器类无限发布通知之后,第二个视图控制器会进入第一个类的 dataDownloadComplete: 方法,尽管我每次都在选择器中指定了不同的方法名称。我不明白错误可能是什么。请帮忙。提前致谢。

4

2 回答 2

1

两个视图控制器都在监听通知,因此应该一个接一个地调用这两个方法。

有几种方法可以解决这个问题。最简单的方法是通知包含某种标识符,视图控制器可以查看它是否应该忽略它。NSNotifications 有一个 userInfo 属性。

NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"viewController1", @"id", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:OP_DataComplete object:self userInfo:info];

当您收到通知时,请检查它是给谁的:

- (void)dataDownloadComplete:(NSNotification *)notification {
    NSString *id = [[notification userInfo] objectForKey:@"id"];
    if (NO == [id isEqualToString:@"viewController1"]) return;

    // Deal with the notification here
    ...
}

还有其他一些方法可以处理它,但在不了解您的代码的情况下,我无法很好地解释它们 - 基本上您可以指定您想要收听通知的对象(请参阅我如何object:self发送但您发送的object:nil)但有时您的架构不会允许这种情况发生。

于 2011-04-08T08:56:11.313 回答
0

最好创建一个协议:

@protocol MONStuffParserRecipientProtocol
@required
- (void)parsedStuffIsReady:(NSDictionary *)parsedStuff;
@end

并声明视图控制器:

@class MONStuffDownloadAndParserOperation;

@interface MONViewController : UIViewController < MONStuffParserRecipientProtocol >
{
  MONStuffDownloadAndParserOperation * operation; // add property
}
...
- (void)parsedStuffIsReady:(NSDictionary *)parsedStuff; // implement protocol

@end

并添加一些后端:到视图控制器

- (void)displayDataAtURL:(NSURL *)url
{
    MONStuffDownloadAndParserOperation * op = self.operation;
    if (op) {
        [op cancel];
    }

    [self putUpLoadingIndicator];

    MONStuffDownloadAndParserOperation * next = [[MONStuffDownloadAndParserOperation alloc] initWithURL:url recipient:viewController];
    self.operation = next;
    [next release], next = 0;
}

并使操作保持在视图控制器上:

@interface MONStuffDownloadAndParserOperation : NSOperation
{
  NSObject<MONStuffParserRecipientProtocol>* recipient; // << retained
}

- (id)initWithURL:(NSURL *)url Recipient:(NSObject<MONStuffParserRecipientProtocol>*)recipient;

@end

并在下载和解析数据时将操作消息发送给收件人:

// you may want to message from the main thread, if there are ui updates
[recipient parsedStuffIsReady:parsedStuff];

还有更多的东西要实现——它只是一种形式。它更安全,涉及直接消息传递、引用计数、取消等。

于 2011-04-08T09:10:56.990 回答