纯代码解释runloop

       最近做项目碰到个问题,具体的操作是在一个线程里面开启一个while循环执行相关的代码,当然功能是实现了但是发现CPU占用率很高,后来查到原因我这样做无疑让这个线程一直处于唤醒的状态这样做太耗资源,通过查资料想到了使用RunLoop。 理论知识推荐这篇文章    http://ios.jobbole.com/85759/ 认真有耐心的看下去会有收获。下面通过代码来详细解决上面碰到的难题。

swift代码:

    overridefunc viewDidLoad() {
       super.viewDidLoad()
       let lockQueue:dispatch_queue_t =dispatch_queue_create(
           "RunLoopQueue",DISPATCH_QUEUE_SERIAL
        )
       dispatch_async(lockQueue) {
           while(true)
            {
               print(".........")
            }
        }
    }

这是我以前的做法运行:


简简单单打印就耗了这么多的cpu,简直了。下面加上runloop:

<span style="font-size:18px;">        dispatch_async(lockQueue) {
           while(true)
            {
               print(".........")
               self.currentRunLoop =NSRunLoop.currentRunLoop()
               //第一种 如果只有这一句没有给它soures,observer,timer则这个RunLoop会直接退出,不进入循环
               self.currentRunLoop.runMode(NSDefaultRunLoopMode, beforeDate:NSDate.distantFuture())
            }
        }</span>

直接运行:


可以看到效果还是一样的感觉runloop没起作用,跟那篇文章讲的一样,因为我们没有为RunLoop添加任何的源,接下来加上source:

<span style="font-size:18px;">        dispatch_async(lockQueue) {
           while(true)
            {
               print(".........")
               self.currentRunLoop =NSRunLoop.currentRunLoop()
               //第二种 加上一个source此时这个线程被带到一个循环里去了
               self.currentRunLoop.addPort(NSPort.init(), forMode: NSDefaultRunLoopMode)
               //第一种 如果只有这一句没有给它soures,observer,timer则这个RunLoop会直接退出,不进入循环
               self.currentRunLoop.runMode(NSDefaultRunLoopMode, beforeDate:NSDate.distantFuture())
            }
        }</span>

直接运行


这是我们发现只被打印一次说明该线程已经被加入到RunLoop中去了,接下来看怎么去唤醒这个runloop,要唤醒RunLoop必须要用performSelector:

  override func viewDidLoad() {
        super.viewDidLoad()
        
        stopBtn.frame = CGRectMake(self.view.frame.origin.x+50, self.view.frame.origin.y+50, 100, 50)
        self.view.addSubview(stopBtn)
        stopBtn.addTarget(self, action: #selector(ViewController.stopRunLoop), forControlEvents:.TouchUpInside)
        let lockQueue:dispatch_queue_t = dispatch_queue_create(
            "RunLoopQueue", DISPATCH_QUEUE_SERIAL
        )
        dispatch_async(lockQueue) {
            while(true)
            {
                print(".........")
                
                self.myThread = NSThread.currentThread()         //获得当前子线程
                print("go in while \(self.count)")
                self.currentRunLoop = NSRunLoop.currentRunLoop() //获得当前子线程的RunLoop
                //第二种 加上一个source 此时这个线程被带到一个循环里去了
                self.currentRunLoop.addPort(NSPort.init(), forMode: NSDefaultRunLoopMode)
                
                //第一种 如果只有这一句 没有给它soures,observer,timer 则这个RunLoop会直接退出,不进入循环
                self.currentRunLoop.runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture())
                
                //CFRunLoopRun() //使用CFRunLoopRun 启动 就可以用CFRunLoopStop来停止
                 print("go in while \(self.count)")
                self.count += 1
                self.myThread.cancel()
                self.myThread = nil
            }
        }

        sleep(2)
        self.performSelector(#selector(ViewController.log), onThread:self.myThread, withObject: nil, waitUntilDone: false) //执行 performSelector 唤醒runloop
    }
    
    func log(){
        count += 1
        print("count = \(count)")
        //CFRunLoopStop(CFRunLoopGetCurrent())
    }
运行:

.........

go in while 0

count = 1

go in while 1

.........

go in while 2

说明达到了唤醒的功能,知道了这些解决我上面说的那个问题应该很简单了!

最后分享一个OC代码很好的例子。

http://download.csdn.net/detail/itpeng523/9588702


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值