这是我的代码。 (忽略其他可能的代码,这是一个空项目,这段代码写在一个空的 UIViewcontroller viewDidLoad 中)
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
println(self)
}
我不明白为什么它在我运行专业版时会崩溃
- thread #1: tid = 0x1a796, 0x00284d18 libswiftCore.dylib`_swift_release_slow + 8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x458bc681)
最新的 beta(5) 是否发生了变化,不再支持? 谢谢
编辑: 有趣的是这段代码适用于 Objc
__weak MyViewController *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@", weakSelf);
});
编辑2: 此链接的解释:Shall we always use [unowned self] inside closure in Swift关于 weak 和 unowned 的区别是错误的。
不仅仅是 weak nils 和 unowned 没有。如果是这样,这也应该崩溃:
dispatch_async(dispatch_get_main_queue()) {
[weak self] in
println(self)
}
但它没有,它打印了指针,所以它不是 nil。
最佳答案
[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)
}
关于ios - Swift ARC 和 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25254588/