这是我的代码。 (忽略其他可能的代码,这是一个空项目,此代码写在一个空的UIViewcontroller viewDidLoad中)
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
println(self)
}
我不明白为什么在我运行专业人员时会崩溃
- 线程#1:tid = 0x1a796,0x00284d18 libswiftCore.dylib`_swift_release_slow + 8,queue = ' com.apple.main-thread',停止原因= EXC_BAD_ACCESS(代码= 1, 地址= 0x458bc681)
最新的测试版(5)发生了什么变化,这是不再支持的了? 感谢
编辑: 有趣的是这段代码适用于Objc
__weak MyViewController *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@", weakSelf);
});
EDIT2: 关于这个链接的解释:Shall we always use [unowned self] inside closure in Swift关于弱者和无人的差异是错误的。
不仅仅是那些弱小的无所事事并没有。如果是这样的话,那也应该崩溃:
dispatch_async(dispatch_get_main_queue()) {
[weak self] in
println(self)
}
但它没有,它打印指针,因此,它不是零。
答案 0 :(得分:9)
[Unowned self]
使得闭包不会创建对self
的强引用,如果它也被解除分配,它也不会自动将其设置为nil
。到异步方法执行时,self已被释放。这就是你遇到崩溃的原因。
在一次性异步调用中使用unowned
当然没有意义。最好是抓住它的强有力的参考,以确保它坚持下去。仍然没有成为一个强大的参考周期,因为self
不拥有闭包。
旁注:这不是您的所有代码,因为self
未在代码中的任何位置定义。
unowned
和weak
是两回事。在Objective-C中,unowned
被称为unsafe unretained
。您可以在两种语言中使用weak
。 weak
表示如果取消分配对象,运行时将自动将引用转换为nil
。 unowned
或unsafe unretained
表示它不会被设置为nil
(这就是为什么它被称为"不安全"在Objective-C中。
Unowned
只应在永远不会释放对象的情况下使用。在这种情况下,请使用weak
。
请记住,如果你在Swift中将变量捕获为weak
,那么引用将是可选的,因此要使用它,你必须打开它:
dispatch_async(dispatch_get_main_queue()) {
[weak self] in
if let actualSelf == self {
// do something with actualSelf
}
// you can still print the "wrapped" self because it is fine to print optionals
// even if they are `nil`
println(self)
}
但要明确的是,在这种情况下使用强引用仍然是最好的:
dispatch_async(dispatch_get_main_queue()) {
println(self)
}