1

我正在使用 AFNetworking 客户端对象,它对 XML 文档发出异步请求并对其进行解析。

还使用NSNotificationCenter在文档完成解析时发布通知。

有没有办法在不阻塞主线程的情况下等待发布通知?

例如代码:

-(void)saveConfiguration:(id)sender {

    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient];

    // Performs the asynchronous fetching....this works. 
    [RESTClient fetchActiveUser:[usernameTextField stringValue] withPassword:[passwordTextField stringValue]];

    /*
     * What do I need here ? while (xxx) ?
     */

    NSLog(@"Fetch Complete.");

}

基本上我想知道在上述指定区域中我需要什么样的代码来确保函数等到提取完成?

就像现在一样,我将看到“获取完成”。在获取完成之前在调试控制台中。

我尝试在 TLHTTPClient 类中添加一个 BOOL 标志:

BOOL fetchingFlag;

然后尝试:

while([RESTClient fetchingFlag]) { NSLog(@"fetching...); } 

当此类收到通知时,它会设置 RESTClient.fetchingFlag = FALSE; 从技术上讲,哪个应该杀死while循环?除了我的while循环无限运行?!

4

2 回答 2

2

基本上我想知道在上述指定区域中我需要什么样的代码来确保函数等到提取完成?

你不需要代码。开始 fetch 后不要在方法中放任何东西,什么都不会发生。您的程序将“等待”(实际上它会处理其他输入),直到收到通知。

在通知处理程序方法中,放置完成获取时需要执行的所有内容。这是通知和其他回调方案的(其中一个)点——您的对象在收到该采取行动的通知之前不会做任何进一步的事情。

有没有办法在不阻塞主线程的情况下等待发布通知?

这正是它的工作原理。

于 2012-04-19T17:56:12.197 回答
0

如果您不需要在任务完成时通知多个对象,您可以在-fetchActiveUser:withPassword:方法中添加一个完成处理程序(objc 块)(这样它就会变成类似-fetchActiveUser:withPassword:completionHandler:并添加要在完成处理程序中执行的代码。

举个例子,假设您的-fetchActiveUser:withPassword:completionHandler:方法如下所示:

- (void)fetchActiveUser:(NSString *)user 
           withPassword:(NSString *)pass 
      completionHandler:(void (^)(TLUser *user, NSError *error))handler
{
    NSURL *URL                   = [NSURL URLWithString:@"http://www.website.com/page.html"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];    
    NSOperationQueue *queue      = [NSOperationQueue currentQueue];
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:queue 
                           completionHandler:^ (NSURLResponse *response, NSData *data, NSError *error) 
    {
        if (!handler) 
        { 
            return 
        };

        if (data) 
        {
            TLUser *user = [TLUser userWithData:data];

            if (user)
            {
                handler(user, nil);
            }
            else
            {
                NSError *error = // 'failed to create user' error ...
                handler(nil, error);
            }
        }
        else
        {
            handler(nil, error);
        }
    }];
}

每当任务完成时,都会调用完成处理程序。如果出现问题(连接错误、解析时数据格式更改等),它将返回 TLUser 对象或错误。

您将能够像这样调用该方法:

- (void)saveConfiguration:(id)sender 
{
    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient];


    // Performs the asynchronous fetching

    [RESTClient fetchActiveUser:[usernameTextField stringValue] 
                   withPassword:[passwordTextField stringValue] 
              completionHandler:^ (TLUser *user, NSError *error)
    {
        if (user)
        {
            NSLog(@"%@", user);
        }
        else
        {
            NSLog(@"%@", error);    
        }
    }];
}

当然,在这个例子中,我使用了 NSURLConnection 的异步构建方法而不是 AFNetworking,但是您应该能够了解大致的概念。

于 2012-04-19T17:29:04.380 回答