ios - Swift ARC 和 block

标签 ios swift automatic-ref-counting

我正在尝试一个简单的示例,如下所示: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-XID_88

这是我的代码。 (忽略其他可能的代码,这是一个空项目,这段代码写在一个空的 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 未在您的代码中的任何位置定义。

unownedweak 是两个不同的东西。在 Objective-C 中,unowned 被称为 unsafe unretained。您可以在两种语言中使用 weakweak 意味着如果对象被释放,运行时会自动将引用转换为 nilunownedunsafe 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/

相关文章:

iphone - UIViewController 似乎没有完全随 ARC 一起发布

iphone - 用于计算关键字的最有效的数据库模式

iphone - 缺少'@end'//@end必须出现在Objective-C上下文中

java - 我的java服务器后端代码需要部署在云中

ios - 按钮在 Storyboard 上看起来不同

ios - 带有 Swift 滑动菜单的空白菜单按钮

ios - 当应用程序进入后台时,navigationItem 的 titleView 中的 searchBar 消失

ios - iPhone View 移动动画

iphone - iOS - 在 ARC 下弹出时 ViewController 未被释放

iphone - 我需要在 ARC 中使用 dealloc 方法吗?