cocoa 线程操作
在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 线程操作的更多相关文章
- winform 跨线程操作控件
当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)
最近在做一个winform的小软件(抢票的...).登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是 ...
- C#跨线程操作控件
1.首先通过按键创建子线程: 创建子线程,子线程调用changeText方法. private void btnOK_Click(object sender, EventArgs e) { Threa ...
- WinForm中跨线程操作控件
在WinForm编程时会遇到通过后台线程操作界面的情况,直接在后台线程执行的方法中直接操作控件会报错,这时候就要使用跨线程方式间接操作控件.下面是两种实现方式. 1.采用定义delegate的方式 ...
- 线程操作案例--生产者与消费者,Object类对线程的支持
本章目标 1)加深对线程同步的理解 2)了解Object类中对线程的支持方法. 实例 生产者不断生产,消费者不断消费产品. 生产者生产信息后将其放到一个区域中,之后消费者从区域中取出数据. 既然生产的 ...
- NSTimer 线程操作
http://www.jianshu.com/p/0c050af6c5ee 2.NSTimer的创建与撤销必须在同一个线程操作.performSelector的创建与撤销必须在同一个线程操作.
- C# 跨线程操作控件(简洁)
C# 跨线程操作控件 .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生.解决此问题的方法有两个: 第一 ...
- 线程操作API
线程操作API 1.currentThread 2.getId() .getName().getPriority().getStart.isAlive().isDaemon().isInterrupt ...
随机推荐
- ToggleButton开关状态按钮控件
ToggleButton开关状态按钮控件 一.简介 1. 2.ToggleButton类结构 父类是CompoundButton,引包的时候注意下 二.ToggleButton开关状态按钮控件使用方法 ...
- python标准日志模块logging使用
python的标准库里的日志系统从Python2.3开始支持.只要import logging这个模块即可使用.如果你想开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,只要这样使用: ...
- LCS 的 NlogN作法
这个算法其实是因为LIS有NlogN的作法,把LCS转化为了LIS来做. 对于序列A{},B{},我们可以记录下来B中的每个元素在A中出现的位置,按顺序保存在一个新序列当中, 如果有多个位置按倒序写, ...
- 移动国家号(MCC)
定义移动国家号 Mobile Country Code (MCC)由三位十进制数组成,它表明移动用户(或系统)归属的国家. 格式移动国家号(MCC)由三个十进制数组成,编码范围为十进制的000-999 ...
- 【ccf2017-12-2】游戏(模拟)
问题描述 有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向. 游戏开始,从1号小朋 ...
- Java8_01_新特性概述
一.前言 二.
- Struts03---参数传递
package cn.bdqn.bean; /** * *用户的实体类 */ public class User { private String name; private String passw ...
- MASM 16位汇编程序几种典型的格式
1.有名段 data segment output db 'Hello world!$' data ends code segment start: assume ds:data,cs:code mo ...
- C语言中的extern关键字用法
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 1. extern修饰变量的声明.举例来说,如果文件a.c需要引用b.c中变量int v ...
- 演示使用Metasploit入侵Windows
我使用Kali Linux的IP地址是192.168.0.112:在同一局域网内有一台运行Windows XP(192.168.0.108)的测试电脑. 本文演示怎么使用Metasploit入侵win ...