• cocoa 线程操作


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

    1. NSPort *port1 = [NSPort port];   
    2. NSPort *port2 = [NSPort port];   
    3. NSArray *userInfonil;   
    4. NSConnection* kitConnection = nil;   
    5. kitConnection = [[NSConnection alloc] initWithReceivePort:port1 sendPort:port2];   
    6. [kitConnection setRootObject:self];   
    7.    
    8. userInfo= [NSArray arrayWithObjects:port2, port1, nil];   
    9. [NSThread detachNewThreadSelector:@selector(newThread:)   
    10.             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  currentRunLooprun];或者runMode:beforeDate,runUntilDate等。

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

    下面是示例代码:

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


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

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

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

    setServer:是主线程中的方法。

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

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

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

    [plain] view plaincopy
    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的引用,不会造成内存泄露。

    [plain] view plaincopy
      1. [(id)[serverConnection rootProxy] setServer: workerObject];   
      2. [workerObject release];  
  • 相关阅读:
    RIP 动态路由
    9.28 二叉树计数
    9.31 取数理论
    花园
    迟滞变化
    AutoHotkey之自问自答
    几种常见的滤波处理
    快速排序(Quicksort)
    浅谈VBA
    新的开始
  • 原文地址:https://www.cnblogs.com/ArRan/p/3784384.html
Copyright © 2020-2023  润新知