MacDev 板


LINE

※ 引述《Dannier (猫尾巴~)》之铭言: : 不好意思小弟不才 : 研究了一下了解了一些NSRunLoop : 可是还是有问题 : 我想要按一个扭开始一直做某件事情 : 按另一个则停止 : 但我还是不知道要怎麽让它停止NSRunLoop : 实在想不出办法来 : 想要请教高手指点....感激不尽(躬) 把你的code删掉了 同样的事,我会用下面的做法: //Do it by Timer @interface MyObject: NSObject { NSTimer* myTimer; } - (IBAction)startTimer:(id)sender; - (IBAction)stopTimer:(id)sender; - (void)timerHandler:(NSTimer*)theTimer; - (void)myTask; @end @implementation MyObject - (IBAction)startTimer:(id)sender { //pseudo code //Start timer with repeat } - (IBAction)stopTimer:(id)sender { //Stop timer } - (void)timerHandler:(NSTimer*)theTimer { //do something before myTask if needed //call myTask //do something after myTask if needed } - (void)myTask { // What your want to repeat. } @end 或者是 //Do it by thread @interface MyObject: NSObject { BOOL isThreadRunning; NSLock* threadStateLock; } - (IBAction)startThread:(id)sender; - (IBAction)stopThread:(id)sender; - (void)myThread:(id)anObject; - (void)myTask; @end @implementation MyObject - (IBAction)startThread:(id)sender { //lock for changing thread state //set isThreadRunning YES //unlock //Start thread with function myThread. } - (IBAction)stopThread:(id)sender { //lock for changing thread state //set isThreadRunning NO //unlock } - (void)myThread:(id)anObject { //Declaring a local variable __isThreadRunning == NO //Do followings //{ // 1. do something before myTask if needed // 2. myTask // 3. do something after myTask if needed // 4. lock for loading thread state // __isThreadRunning = isThreadRunning // unlock //}while(__isThreadRunning == YES) } - (void)myTask { // What your want to repeat. } @end 我的原则是,尽量解说原理,而不提供实际的程式。 在我之前的文章中,已经提到过,NSRunLoop在使用上有一些条件。 我所没有明确的提出的是,你的需求并不适宜使用NSRunLoop。 关於这点,icecicada的文章中说得很清楚,你所需要使用的是NSThread或NSTimer。 在这里,我再解释得清楚一点: 1. 执行绪与Run Loop是不同的两回事。 所谓的多绪,指的是「同时进行」的工作。在多核心,或是多处理器的环境下, 要达到「同时进行」的目的,可将不同的执行绪,交由不同的核心去处理如下: T1(task 1) T2(task2) | | | | ↓ ↓ 而RunLoop呢,其实是用来实现所谓的「分时多工」,其动作如下: T1 |←────┐ |(task 1) | | | |(task 2) | | | └─────┘ 在过去单核单处理器的情形下,因为多绪的「同时进行」一事,也是用「分时多工」的 方式去达成,所以有时会比较容易搞混。 2. NSRunLoop本质上虽然是一个回圈,但与while(),for()的意义及使用目的不同。 如前所述,NSRunLoop是用来实现「分时多工」的,所以里面除了「重复」外, 还会做所谓的Dispatch,也就是「工作分配」。 但while() 及for()这种基础的回圈,就只是很单纯的「重复」。 3. 回到你的需求,你希望 a.重复做某件事 b.当满足某条件时,停止a. 你可以很清楚的看到,你的需求a,只有「重复」的要求而已,而不需要「分配工作」。 因此你根本不需要用到NSRunLoop来帮你做事。 至於需求b,则可以用「分时」的方式,或是「多绪」的方式择一来达成。 也就是在这里,你可能搞混了,误以为你的需求 a+b 一定要存取到NSRunLoop。 多绪的方式,上面的虚拟码应该已经很清楚,我这边讲解一下「分时」的做法。 首先,如icecicada所述,在Cocoa应用程式执行时,其实已经有一个NSRunLoop在跑了。 它看起来可能像是下面这样: Main Thread |←───────┐ |(do GUI task) | |(get event) | |(dispatch event)| |(blahblah...) | └────────┘ 我们可以看到,在这个Run Loop中,其实已经有许多重复的工作了, 这些重复的工作,负责维护应用程式的各种状态, 并处理使用者对应用程式所做的各类动作。 而当你想要「重复」某件工作时,在597篇你做的事是: Main Thread |←───────┐ |(do GUI task) | |(get event) | ┌┤(dispatch event)|(blahblah...) | └────────┘ └→ 1.如果startEvent: 1.1 doLoop:(进入回圈) 1.1.1 do something 因为在1.1,你进入了一个回圈,造成Main thread一直停在一个副回圈中, 所以无法再继续进行get event, dispatch event,do other things的流程。 在分时的情况下,你真正应该做的事是像下面这样: Main Thread |←───────┐ |(do GUI task) | |(get event) | |(dispatch event)| |(blahblah...) | |1.1.1 do something (将1.1.1加入Run Loop) └────────┘ 这也是你在上一篇所试着要做的。 但是,虽然你试着要将一个新工作加入Run Loop, 但因为你没有弄清楚NSTimer与NSRunLoop的角色,所以会写出一些多余的程式。 当你在产生一个NSTimer,并将之与某个Selector结合时, 其实就已经帮你做好上面所描述的事情了,所有与NSRunLoop相关的操作, 都已经在NSTimer的实作中帮你做完了,你不需要自己再去做一次。 你要做的只有: 1. 产生一个NSTimer,并指定要做的事情(Selector) 2. 起动(fire)所产生的Timer 在2.的时候,NSTimer就会自动帮你将Selector加入Current Run Loop。 而当你呼叫[NSTimer invalidate]时,NSTimer就会帮你把方才加入的Selector, 移出Current Run Loop. 从上面,你也可以看出,为何icecicada会说: 「如果是一直在执行,或是执行需要花费较长的时间,还是使用Theard会比较好...」 因为你还是在同一个Thread中,而不是不同的Thread。 而使用多绪的方式,执行起来会像下面: Main Thread child |←───────┐ |←───────┐ |(do GUI task) | |(do 1.1.1) | |(get event) | └───┬────┘ |(dispatch event)| | |(blahblah...) | | └───────┬┘ | └────→A←─┘ 这时候要让child停下来,就得有一个变数A,能够同时让Main Thread与child存取。 这样你才能在Main Thread中改变A的状态, 而在Child中检查A的状态,并决定要不要停下来。 至於更详细的class用法,还是请你去查一下NSTimer,NSThread的文件, 并参考一下别人的范例。 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 219.84.252.229
1F:推 Dannier:感谢你 真的是说明的很清楚 我今天自己有利用新产生一个 05/12 20:36
2F:→ Dannier:Thread然後加工作到里面结果可以执行了 不过我觉得我还是 05/12 20:37
3F:→ Dannier:有多写了一些步骤 我会再多用清楚一点的 谢谢感激不尽! 05/12 20:40







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Tech_Job站内搜寻

TOP