对Cocoa中新建线程的一点点理解
来源:互联网 发布:免费的网管软件 编辑:程序博客网 时间:2024/05/07 02:00
在Cocoa 中创建线程使用NSThread类的detachNewThreadSelector: toTarget:withObject:方法
NSPort *port1 = [NSPort port]; NSPort *port2 = [NSPort port]; NSArray *userInfo= nil; NSConnection* kitConnection = nil; kitConnection = [[NSConnection alloc] initWithReceivePort:port1 sendPort:port2]; [kitConnection setRootObject:self]; userInfo= [NSArray arrayWithObjects:port2, port1, nil]; [NSThread detachNewThreadSelector:@selector(newThread:) 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)。
下面是示例代码:
- (void)newThread:(id)userInfo { NSAutoreleasePool *pool; NSConnection *serverConnection; mySubThread *subThreadWorker; pool = [[NSAutoreleasePool alloc] init]; serverConnection= [NSConnection connectionWithReceivePort:[userInfo objectAtIndex:0] sendPort:[userInfo objectAtIndex:1]]; subThreadWorker = [[mySubThread alloc] init]; [serverConnection setRootObject: self]; //do something; do { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } while (![subThreadWorker shouldExit]); [subThreadWorker release]; [pool release]; return; }
在 serverConnection= [NSConnection connectionWithReceivePort:[userInfo objectAtIndex:0] sendPort:[userInfo objectAtIndex:1]];完成之后,
要建立主线程和子线程之间的通信,还需要在//do something之前加上这样一句代码:
[(id)[serverConnection rootProxy] setServer: subThreadWorker];
setServer:是主线程中的方法。
执行这个方法,是为子线程在主线程中设置一个代理。
这样,在主线程中,就可以通过这个代理,来响应和执行子线程中的一些消息了。
下面给出一个主线程中的setServer:的示例:
- (void)setServer:(id)anObject { [anObject setProtocolForProxy:@protocol(WorkerMethods)]; work = (id <WorkerMethods>)[anObject retain]; return; }
其中,work就相当于子线程在主线程的代理。
在主线程中,只要使work作为子线程消息的接收者,就可以响应和执行子线程的消息啦。
至此,主线程和子线程之间的连接就建立起来了。
此外,需要注意的一点是:在setServer:中我们看到,传入的参数anObject是被retain了的。
因此,在子线程newThread:中,在调用了setServer:之后,可以将参数release掉。
这样,主线程唯一保有work的引用,不会造成内存泄露。
[(id)[serverConnection rootProxy] setServer: workerObject]; [workerObject release];
- 对Cocoa中新建线程的一点点理解
- 对线程的一点点新理解
- 对jsp的一点点理解
- 对指针的一点点理解
- 对static的一点点理解
- 对Thrift的一点点理解
- 对Thrift的一点点理解
- 对Dijkstra的一点点理解。
- 对Oracle中分组函数的一点点理解
- 对Java中String类的一点点理解
- 对MFC原理的一点点理解
- 我对搜索算法的一点点理解
- 对局部性原理的一点点理解
- 对JS闭包的一点点理解
- 浅谈Java中对线程的理解
- 对线程的理解
- 对指针运算符*文字说明的一点点理解
- 我对C++ Traits编程技法的一点点理解
- Android开发当中Parcelable,Serializable接口的使用
- compass 使用详解
- vimrc Fedora
- ini_setini_get 可操作配置参数列表
- 实体关系之@OneToMany
- 对Cocoa中新建线程的一点点理解
- Android中ListView点击和ListView的item里面的Button或ImageView不能同时生效问题的解决
- 第十日
- 相似图片搜索的原理
- HTTP Header 描述
- 浅谈为什么大电容滤低频小电容滤高频的问题
- Apache 局域网内不能访问
- linux子进程fork
- .bashrc 5.19