【问题标题】:NSnotifications for multiple downloads用于多次下载的 NSnotifications
【发布时间】:2011-04-08 08:18:50
【问题描述】:

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

 [[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: 方法,尽管我每次都在选择器中指定了不同的方法名称.我不明白错误可能是什么。请帮忙。提前致谢。

【问题讨论】:

    标签: iphone objective-c nsnotifications


    【解决方案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) 但有时您的架构不允许这种情况发生。

    【讨论】:

    • 嗨,Dean,谢谢,这更容易,我现在使用字典并传递它的 objectForKey。它有效。
    【解决方案2】:

    最好创建一个协议:

    @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];
    

    还有一些东西要实现——它只是一个表单。它更安全,涉及直接消息传递、引用计数、取消等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多