Developing IOS 7 Apps for iPhone and iPad (Lecture 10)

来源:互联网 发布:幽浮2优化 编辑:程序博客网 时间:2024/04/30 06:49

多线程和Scroll View

大纲

  • 多线程(Multithreading)

将blocks记录到队列(Queues)中(这些blocks将会稍后再其他线程上被执行)

(Vlad_W: 个人理解是你可以把每一个线程看作一个队列)

  • UIScrollView
一个在任意大content上,并且可以被移动和缩放的“窗口”
  • Demo
Imaginarium
  • UITableView
Data source驱动的一个纵向views列表


多线程

  • 队列

多线程在ios中和队列紧密相连。

Blocks被排列在队列中(methods的调用同样可以被加入队列中),然后这些队列中的Blocks会脱离出队列,并且在其他相应线程上执行。

  • 主队列(Main Queue)

主队列是一个非常特殊的队列。

所有的界面活动(UI activity)必须也只能出现在这个主队列中。

而且,恰恰相反,所有的非界面活动任何时候都不能出现在主队列中。因为我们希望我们的界面总是可以被响应的。

  • 其他队列

大部分的ios会因为需求为我们创建其他队列。

这节课我们大概介绍一下如何创建自己的队列(但是通常我们并不需要这么做)。

  • 在另一个队列上执行一个block

<span style="font-size:14px;">dispatch_queue_t queue = ...;dispatch_async(queue, ^{ });</span>

  • 得到主队列
<span style="font-size:14px;">dispatch_queue_t mainQ = dispatch_get_main_queue();NSOperationQueue *mainQ = [NSOperationQueue mainQueue]; // for object-oriented APIs</span>
  • 创建一个队列(非主队列)
<span style="font-size:14px;">dispatch_queue_t otherQ = dispatch_queue_create(“name”, NULL); // name a const char *!</span>
  • 简单模型:调用一个主队列上的method

<span style="font-size:14px;">NSObject method ...  - (void)performSelectorOnMainThread:(SEL)aMethod                           withObject:(id)obj<span style="white-space:pre"></span>   waitUntilDone:(BOOL)waitUntilDone; </span>
<span style="font-size:14px;">dispatch_async(dispatch_get_main_queue(), ^{ /* call aMethod */ });</span>
  • 例子:使用多线程的IOS API
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL urlWithString:@“http://...”]];NSURLConfiguration *configuration = ...;NSURLSession *session = ...;NSURLSessionDownloadTask *task;task = [session downloadTaskWithRequest:request                        completionHandler:^(NSURL *localfile, NSURLResponse *response, NSError *error) {/* want to do UI things here, can I? */ }];[task resume];
<span style="font-size:18px;">downloadTaskWithRequest:<span style="font-family: Arial, Helvetica, sans-serif;">completionHandler:会在非主线程中执行“下载url”的工作。</span></span>
<span style="font-size:18px;"><span style="font-family: Arial, Helvetica, sans-serif;">(如之前所说,因为不是在主线程上执行该工作,所以就算这个工作在等待网络响应的时候,也不会影响UI的正常运作)</span></span>

  • 在主队列上
 NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration                                                        delegate:nil                                                   delegateQueue:[NSOperationQueue mainQueue]];  NSURLSessionDownloadTask *task;  task = [session downloadTaskWithRequest:request                        completionHandler:^(NSURL *localfile, NSURLResponse *response, NSErr or *error) {    /* yes, can do UI things directly because this is called on the main queue */ 
  }];  [task resume];

因为delegateQueue是主队列,所以completionHandler将会在主队列上。

当URL的下载完成时,上面代码中的block会在主队列上执行。

因此我们可以在这写任何关于UI的代码。

当然,如果你在这里(主队列)做非UI的事情,你最好快一些,避免通过占用主队列而阻碍了UI的响应。

  • 不在主队列上
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; // no delegateQueue NSURLSessionDownloadTask *task; task = [session downloadTaskWithRequest:request                        completionHandler:^(NSURL *localfile, NSURLResponse *response, NSError *error) {      dispatch_async(dispatch_get_main_queue(), ^{ /* do UI things */ });      or [self performSelectorOnMainThread:@selector(doUIthings) withObject:nil waitUntilDone:NO];  }];  [task resume];

在以上例子中,你不能做任何和UI相关的事情,因为completionHandler不在主队列上。

如果你想要做UI相关的事情,你必须将一个block或者method添加回主队列上。




0 0