的存在completionHandler
可能会导致人们从逻辑上推断这setGroupWithName
是一种异步方法。这是 iOS 开发中常见的编程模式:与其在前台执行一些可能耗时的过程(在此期间用户界面将被冻结),不如在后台异步执行,但传递一个 block,completionHandler
在这种情况下,所以您可以确定异步过程完成后应该发生什么。
在这种情况下,您似乎正在setGroupWithName
某个后台线程/队列上调用 ,并理解在发生这种情况时,您将继续在主线程上(在您的情况下,在该NSLog
语句中),确保您的应用程序保持响应而那个缓慢的操作正在完成。但是当那个异步后台操作setGroupWithName
完成时,它将执行由代表的代码块completionHandler
(在你的情况下,设置s
to @"something"
)。
如果你在你设置为NSLog
的块内放置一个语句,你可能会看到它在调用.completionHandler
s
@"something"
NSLog
setGroupWithName
为了说明这个例子,这里是一个标准 Cocoa 方法的例子,它有一个completionHandler
参数,即NSURLConnection
类方法,sendAsynchronousRequest
.
问题是如何执行缓慢的操作,但仍然拥有响应缓慢的用户界面,而无需等待缓慢的 Internet 操作。
因此,请考虑以下代码:
- (void)performSearch:(NSString *)term
{
NSLog(@"%s start: array has %d items", __FUNCTION__, [self.array count]);
// prepare to do search (the details here are not relevant)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://search.twitter.com/search.json?q=%@", term]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// submit an Internet search that will be performed in the background
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// in the background, when the Twitter search is done,
// and when it's done, we'll make an array of the results
self.array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"%s: after background query, array now has %d items", __FUNCTION__, [self.array count]);
}];
// in the meantime, let's immediately carry on while that search is taking place
NSLog(@"%s end: array still has %d items", __FUNCTION__, [self.array count]);
}
这段代码的细节不是很重要,但基本思想是它做的很慢(在互联网上执行推特搜索),但它会立即在主线程中继续运行代码,让后台线程继续运行自己的节奏。
各种NSLog
语句的时间戳说明了所有这些的时间安排:
2013-05-02 20:42:58.922 myapp[81642:c07]-[ViewController performSearch:] 开始:数组有 0 个项目
2013-05-02 20:42:58.923 myapp[81642:c07] -[ViewController performSearch:] 结束:数组仍有 0 个项目
2013-05-02 20:42:59.798 myapp[81642:1303] __32-[ViewController performSearch:]_block_invoke:后台查询后,数组现在有 11 个项目
请注意,“开始”和“结束”之间经过的时间大约为 1 毫秒,但在后台完成 Twitter 搜索几乎需要整整一秒。设计原则是,如果我们不异步执行此操作,completionHandler
在这种情况下使用 ,应用程序的用户界面将在那一秒钟内被冻结。但是通过使用异步编程技术,该应用程序仍然很好并且响应迅速,而是在后台执行缓慢的操作。
我不熟悉您的setGroupWithName
方法,但它可能正在执行相同类型的异步操作。因此,您尝试在之后立即查看该值不会反映该方法完成后将更改的值(有点像我示例中的“结束”NSLog 语句不反映将发生的更改的事实)秒后)。