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

多线程和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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值