
现在我有一个程序片段如下:
| 复制代码 - (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全部内容,希望文章能够帮你解决runloop所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)