在Cocoa 中创建线程使用NSThread类的detachNewThreadSelector: toTarget:withObject:方法

  1. NSPort *port1 = [NSPort port];
  2. NSPort *port2 = [NSPort port];
  3. NSArray *userInfo= nil;
  4. NSConnection* kitConnection = nil;
  5. kitConnection = [[NSConnection alloc] initWithReceivePort:port1 sendPort:port2];
  6. [kitConnection setRootObject:self];
  7. userInfo= [NSArray arrayWithObjects:port2, port1, nil];
  8. [NSThread detachNewThreadSelector:@selector(newThread:)
  9. toTarget:target withObject:userInfo];

newThread:就是我们要创建的线程。它需要一个参数,返回值为空。

-(void)newThread:(id)userInfo

target:用来在创建的线程中接收newThread的消息。

userInfo:主线程传给新建线程的参数。

另外,注意主线程和子线程中的connection的port顺序。

在-(void)newThread:(id)userInfo中需要了解的是:

1)首先,需要创建一个自动释放池。

2)在新建的线程的执行过程中,target和userInfo是retain的,线程结束后会自动的release掉。

3)target一旦完成了newThread,线程即刻结束。

4)为了使线程处于活跃状态,以便在稍后进行通信,需要在newThread中加入:

[[NSRunLoop  currentRunLoop] run];或者runMode:beforeDate,runUntilDate等。

一般情况下,应用程序不需要创建和管理NSRunLoop类。每个NSThread,包括应用程序主线程都有一个自动为其创建的NSRunLoop对象,然而只有使用Application Kit的应用程序主线程会自动运行它的运行循环(run loop),除此之外的线程(或 Foundation Kit tools)必须显式的运行它们自己的运行循环(run loop)。

下面是示例代码:

  1. - (void)newThread:(id)userInfo
  2. {
  3. NSAutoreleasePool *pool;
  4. NSConnection *serverConnection;
  5. mySubThread *subThreadWorker;
  6. pool = [[NSAutoreleasePool alloc] init];
  7. serverConnection= [NSConnection
  8. connectionWithReceivePort:[userInfo objectAtIndex:0]
  9. sendPort:[userInfo objectAtIndex:1]];
  10. subThreadWorker = [[mySubThread alloc] init];
  11. [serverConnection setRootObject: self];
  12. //do something;
  13. do
  14. {
  15. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
  16. beforeDate:[NSDate distantFuture]];
  17. } while (![subThreadWorker shouldExit]);
  18. [subThreadWorker release];
  19. [pool release];
  20. return;
  21. }

在 serverConnection= [NSConnection connectionWithReceivePort:[userInfo objectAtIndex:0] sendPort:[userInfo objectAtIndex:1]];完成之后,

要建立主线程和子线程之间的通信,还需要在//do something之前加上这样一句代码:

  1. [(id)[serverConnection rootProxy] setServer: subThreadWorker];

setServer:是主线程中的方法。

执行这个方法,是为子线程在主线程中设置一个代理。

这样,在主线程中,就可以通过这个代理,来响应和执行子线程中的一些消息了。

下面给出一个主线程中的setServer:的示例:

  1. - (void)setServer:(id)anObject
  2. {
  3. [anObject setProtocolForProxy:@protocol(WorkerMethods)];
  4. work = (id <WorkerMethods>)[anObject retain];
  5. return;
  6. }

其中,work就相当于子线程在主线程的代理。

在主线程中,只要使work作为子线程消息的接收者,就可以响应和执行子线程的消息啦。

至此,主线程和子线程之间的连接就建立起来了。

此外,需要注意的一点是:在setServer:中我们看到,传入的参数anObject是被retain了的。

因此,在子线程newThread:中,在调用了setServer:之后,可以将参数release掉。

这样,主线程唯一保有work的引用,不会造成内存泄露。

    1. [(id)[serverConnection rootProxy] setServer: workerObject];
    2. [workerObject release];

cocoa 线程操作的更多相关文章

  1. winform 跨线程操作控件

    当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...

  2. 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

    在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...

  3. WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)

    最近在做一个winform的小软件(抢票的...).登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是 ...

  4. C#跨线程操作控件

    1.首先通过按键创建子线程: 创建子线程,子线程调用changeText方法. private void btnOK_Click(object sender, EventArgs e) { Threa ...

  5. WinForm中跨线程操作控件

    在WinForm编程时会遇到通过后台线程操作界面的情况,直接在后台线程执行的方法中直接操作控件会报错,这时候就要使用跨线程方式间接操作控件.下面是两种实现方式.   1.采用定义delegate的方式 ...

  6. 线程操作案例--生产者与消费者,Object类对线程的支持

    本章目标 1)加深对线程同步的理解 2)了解Object类中对线程的支持方法. 实例 生产者不断生产,消费者不断消费产品. 生产者生产信息后将其放到一个区域中,之后消费者从区域中取出数据. 既然生产的 ...

  7. NSTimer 线程操作

    http://www.jianshu.com/p/0c050af6c5ee 2.NSTimer的创建与撤销必须在同一个线程操作.performSelector的创建与撤销必须在同一个线程操作.

  8. C# 跨线程操作控件(简洁)

                                              C# 跨线程操作控件 .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生.解决此问题的方法有两个: 第一 ...

  9. 线程操作API

    线程操作API 1.currentThread 2.getId() .getName().getPriority().getStart.isAlive().isDaemon().isInterrupt ...

随机推荐

  1. mysql 如果数据不存在,则插入新数据,否则更新 的实现方法

    CREATE TABLE `table_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `my_key` int(11) NOT NULL DEFAULT ...

  2. WPF 自定义依赖属性

      原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html    DependencyObject和Dependen ...

  3. 卸载MicrosoftBAF(删除C:\CommonFramework\instdata.dat)

    发现有个可疑文件夹 C:\CommonFramework ,而且还会不停的删除创建 C:\CommonFramework\instdata.dat 最后被发现这是必应的一个框架程序在捣鬼,在微软论坛里 ...

  4. 用verilog来描述组合逻辑电路

    1,什么是组合逻辑电路? 逻辑电路在任何时刻产生的稳定的输出信号仅仅取决于该时刻的输入信号,而与过去的输入信号无关,即与输入信号作用前的状态无关,这样的电路称为组合逻辑电路. 上图给出了一个典型的数字 ...

  5. SpringMVC4整合CXF发布WebService

    SpringMVC4整合CXF发布WebService版本:SpringMVC 4.1.6,CXF 3.1.0项目管理:apache-maven-3.3.3 pom.xml <project x ...

  6. 010——VUE中使用lodash库减少watch对后台请求的压力

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 集合中的工具类Collections和Arrays

    集合框架的工具类: Collections: 方法sort(): List<String> list = new ArrayList<String>();        lis ...

  8. 2017.11.18 IAP下载(STM8,PIC,STM32)

    客户要求用IAP下载,mark一下,客户还给了stm32的引导码.仅供参考. 1 PIC单片机的IAP  2 STm32 IAP https://www.cnblogs.com/WeyneChen/p ...

  9. 【数据库】mysql数据库缓存

    配置文件在 /etc/mysql/my.cnf ################### 第一部分:查询数据库缓存相关变量 ################### show variables like ...

  10. iOS编译集成linux开源c库的一些记录

    最近一个iOS项目需要使用一些Linux下面的开源c库,说是Linux的其实是跨平台的,各种Unix系统都有支持.理论上iOS来自MacOS,而MacOS其实是一种兼容的Unix系统,所以这些库应该也 ...