iOS使用多线程提高数据并发访问 之五

发布时间:2020-07-06 10:47:03 作者:iKingLai
来源:网络 阅读:745

你的线程入口


当启动线程时,你需要有一些代码来管理当前线程的状态,线程创建和执行的内存,还有在线程内部抛出的异常。原因是你新创建的线程会有自己的栈,它和默认的栈是不同的,如图 6-4。因此,你线程使用的内存和主线程使用的内存是不同的。异常也类似;它只会存储在你的栈中,并不会返回到主栈和主线程中。


iOS使用多线程提高数据并发访问 之五

有很多事情你需要记住:


我会讨论为什么要实现他们已经如何实现他们。


表格6-3 提供了一个简短的演示,让你复习一下创建和配置线程的主要技术,以及他们的优缺点。

iOS使用多线程提高数据并发访问 之五

Autorelease Pool


在应用的每一个线程中,你应该总是要有一个Autorelease Pool,通过把代码放在@autorelease中块中。这个pool会包含所有的autoreleased对象,当线程运行的时候。如果你没有调用返回一个autoreleased对象的方法,最好还是包含@autorelease,因为系统底层的frameworks和libraries也会创建和返回autoreleased对象。如果你有一个@autorelease,而从没使用它,一切依然能够正常运行。


如果你通过Xcode模板创建的应用,你会看到main方法中有下面的代码:


int main(int argc, char *argv[]) {

   @autoreleasepool {

           int retVal = UIApplicationMain(argc, argv, nil, nil);

   }

   return retVal;

}


@autorelease将会处理线程内部所有的autoreleased对象。你可能已经知道,autoreleased对象是

一个你不再使用的,但是你又不想立即释放的对象。它同样可以使用类似[NSMutableArray array]这样的工厂方法来返回一个autorelease对象;。这些对象将在run loop结束时被release。


因此,如果你创建了一个新的线程,确保你的代码包裹在@autorelease块中,像这样:


- (void)myThreadMethod {

       @autoreleasepool { // Top-level pool

       // Do thread work here.

       }

}


ExceptionHandler


在处理线程时,异常是非常重要的。因为每一个线程都有它自己的栈,当发生一个异常时,它将会跟踪所有的方法直到栈的顶部。这可能导致你的线程停止运行。任何主线程中的exception handler将会被忽略。


下面是一个处理异常的基本代码:


NSObject *myObject = nil;

@try {

   // access to some objects inside an array

   myObject = [myArray objectAtIndex:2];

}

@catch ( NSException *e ) {

       NSLog(@"Array has fewer than 3 items");

}

@finally {
       // clean up code here

}


Run Loop


当你创建一个新的线程后,你有两种方法来执行它。

  • 在线程内部编写代码来执行你的逻辑,直到任务执行完毕,而没有什么中断。比如,之前介绍过的从URL现在图片的代码。显然,这是比较简单的。

  • 当有动态事件发生时,你想要你的线程做出响应。比如监听网络上的socket或在某个特定时间触发的事件。这和第一种情况是不同的,需要你在创建一个新的run loop。


下面是一个简单的代码,在一个RunLoop中监听一个输入流:


  1. NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [iStream setDelegate:self];
    [iStream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];



注意:如果[NSRunLoop currentRunLoop]方法是在一个线程中调用,而不是一个run loop,这个方法创建一个新的run loop。



如果你想要在开始运行之前,让一个run loop来等待一段时间,你可以使用NSTimer:


  1. [NSTimer scheduledTimerWithTimeInterval:2.0target:self

    selector:@selector(doStuff)userInfo:nil

    repeats:YES];


但是,有些情况你不应该使用RunLoop,比如在主线程中你有事件处理代码,如NSInputStream或NSTimer工作在一些敏感的任务上,要花费很长的时间才能完成。因为事件处理代码,像我的这个例子,最终会运行在创建它的线程上,你的线程不能继续运行其他事件处理代码,直到旧的事件处理完毕。这对UI主线程是非常有害的,如果你在线程内部创建了timer或input stream run loop。主要的问题是它使得你的UI变得更不灵敏。





推荐阅读:
  1. php商城网站如何提高性能和并发访问
  2. 并发编程之多线程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

ios 性能优化

上一篇:关于spring boot多线程的案例分析

下一篇:MySQL如何创建用户和进行权限管理

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》