runloop

runloop,第1张

概述现在说说runloop为何会成为cocoa开发中迷惑的点。因为很多新手没有从动态角度看它。 首先回想一下第2点介绍的runtime的概念。 接着我出一个题思考一下。    现在我有一个程序片段如下:  复制代码 - (void)myThread:(id)sender {     NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];    现在说说runloop为何会成为cocoa开发中迷惑的点。因为很多新手没有从动态角度看它。 首先回想一下第2点介绍的runtime的概念。 接着我出一个题思考一下。 
 
现在我有一个程序片段如下: 
复制代码 - (voID)myThread:(ID)sender {     NSautoreleasePool *pool=[[NSautoreleasePool alloc] init];     while (TRUE) {                  //do some jobs        //break in some condition                  usleep(10000);                  [pool drain];     }          [pool release]; }
 
现在要求,做某些设计,使得当这个线程运行的同时,还可以从其它线程里往它里面随意增加或去掉不同的计算任务。 这,就是NSRunloop的最原始的开发初衷。让一个线程的计算任务更加灵活。 这个功能在c,c++里也许可以做到但是非常难,最主要的是因为语言能力的限制,以前的程序员很少这么去思考。 
 
好,现在我们对上面代码做一个非常简单的进化: 
 
复制代码 NSMutableArray *targetQueue; NSMutableArray *actionQueue;
- (voID)myThread:(ID)sender {     NSautoreleasePool *pool=[[NSautoreleasePool alloc] init];     while (TRUE) {                  //do some jobs         //break in some condition         int n=[targetQueue count];         assert(n==[actionQueue count]);         for(int i=0;i<n;i++){             ID target=[targetQueue objectAtIndex:i];             SEL action=NSSelectorFromString([actionQueue objectAtIndex:i]);             if ([target respondsToSelector:action]) {                 [target performSelector:action withObject:nil];             }         }                          usleep(10000);                  [pool drain];     }          [pool release]; }
 
注意,这里没有做线程安全处理,记住Mutable container is not thread safe. 
这个简单的扩展,让我们看到了如何利用runtime能力让线程灵活起来。当我们从另外线程向targetQueue和actionQueue同时加入对象和方法时候,这个线程函数就有了执行一个额外代码的能力。 
 
但,有人会问,哪里有runloop? 那个是 nsrunloop? 看不出来啊。 
复制代码 while (TRUE) { //break in some condition }
 
一个线程内这个结构就叫线程的runloop,   它和NSRunloop这个类虽然名字很像,但完全不是一个东西。以前在使用静态语言开始时候,程序员没有什么迷惑,因为没有NSRunloop这个东西。 我接着来说,这个NSRunloop是如何来得。 
 
第二段扩展代码里面确实没有NSRunloop这个玩意儿,我们接着做第3次改进。 这次我们的目的是把其中动态部分抽象出来。 
 
复制代码
@interface MyNSTimer : NSObject {   ID target;   SEL action;   float interval;   CFabsoluteTime lasttime; } - (voID)invoke; @end
@implementation MyNSTimer - (voID)invoke; {   if ([target respondsToSelector:action]) {         [target performSelector:action withObject:nil];     } } @end
 
 
 
复制代码 @interface MyNSRunloop : NSObject {   NSMutableArray *timerQueue; } - (voID)addTimer:(MyNSTimer*)t; - (voID)executeOnce; @end
@implementation MyNSRunloop - (voID)addTimer:(MyNSTimer*)t; {   @synchronized(timerQueue){       [timerQueue addobject:t];     } } - (voID)executeOnce; {   CFabsoluteTime currentTime=CFabsoluteTimeGetCurrent();   @synchronized(timerQueue){       for(MyNSTimer *t in timerQueue){           if(currentTime-t.lasttime>t.interval){               t.lasttime=currentTime;                   [t invoke];           }       }   } } @end
 
 
复制代码 @interface MyNSThread : NSObject {   MyNSRunloop *runloop; } - (voID)main:(ID)sender; @end
@implementation MyNSThread - (voID)main:(ID)sender {     NSautoreleasePool *pool=[[NSautoreleasePool alloc] init];     while (TRUE) {         //do some jobs         //break in some condition         [runloop executeOnce];         usleep(10000);         [pool drain];     }     [pool release]; } @end
 
 
走到这里,我们就算是基本把Runloop结构抽象出来了。例如我有一个MyNSThread实例,myThread1。我可以给这个实例的线程添加需要的任务,而myThread1内部的MyNSRunloop对象会管理好这些任务。 
 
复制代码 MyNSTimer *timer1=[MyNSTimer scheduledTimerWithTimeInterval:1                                                    target:obj1                                                  selector:@selector(download1:)]; [myThread1.runloop addTimer:timer1];
MyNSTimer *timer2=[MyNSTimer scheduledTimerWithTimeInterval:2                                                    target:obj2                                                  selector:@selector(download2:)]; [myThread1.runloop addTimer:timer2];
    当你看懂了上面的代码也许会感叹,‘原来是这么回事啊!为什么把这么简单的功能搞这么复杂呢?’ 其实就是这么回事,把Runloop抽象出来可以使得线程任务管理更加loose coupling,给设计模式提供更大的空间。这样第三方开发者不需要过深入的涉及线程内部代码而轻松管理线程任务。另外请注意,这里MyNSRunloop,MyNSTimer等类是我写得一个模拟情况,真实的NSRunloop实现肯定不是这么简单。这里只为了说明一个思想。这种思想贯穿整个cocoa framework从界面更新到event管理。 总结

以上是内存溢出为你收集整理的runloop全部内容,希望文章能够帮你解决runloop所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1060509.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存