我是否需要使用线程类捕获自我?

时间:2016-10-25 14:35:58

标签: swift grand-central-dispatch weak-references

我有这段代码:

myThreadTemp = Thread(target: self, selector: #selector(threadMain), object: nil)

 @objc func threadMain(data: AnyObject) {
        let runloop = RunLoop.current
        runloop.add(NSMachPort(), forMode: RunLoopMode.defaultRunLoopMode)
        while !Thread.current.isCancelled{
                //foreground
                DispatchQueue.main.async {[weak self] in

                self?.somemethod()
                self?.somevar = 1
                    print("tick")
                }
            if Thread.current.isCancelled {

            }
            Thread.sleep(forTimeInterval: 1.0)
        }
        runloop.run(mode: RunLoopMode.defaultRunLoopMode, before: NSDate.distantFuture)

    }

或者我可以这样做:

DispatchQueue.main.async {
                self.somemethod()
                self.somevar = 1
                    print("tick")
                }

我看到了这个:

Shall we always use [unowned self] inside closure in Swift

但是,如果使用@objc func

1 个答案:

答案 0 :(得分:1)

第一个例子看起来无限期地旋转runloop,在ticks之间等待1秒,而第二个例子将在下一次运行循环迭代时执行一次。在第二种情况下捕获自身方面没有内存管理问题,实际上因为它只执行一次而且块被释放后(打破了self和块之间存在的瞬时保留循环)。

假设你试图每1秒打一次(正如我根据你的问题猜测),有一种更好的方法可以做你想做的事情,using a timer

// Must be executed on main thread, or other NSRunLoop enabled thread, 
// or the below code will silently do nothing.
self.timer = Timer(timeInterval: 1.0, repeats: true) { [weak self] _ in
    self?.someMethod()
    self?.someVar = 1
    print("tick")
}

// Somewhere in the future, to stop the timer:
// self.timer.invalidate()

正如您在上面的示例中所看到的,对于计时器情况,您可能确实想要使用无主或弱引用来引用self(因为计时器块否则将强烈引用self,并自我定时器)。该块也应该在使计时器失效时被释放,所以即使在这种情况下,弱参考也不是100%必要的。