在Swift中不能弱关闭 [英] Can't make weak reference to closure in Swift

查看:139
本文介绍了在Swift中不能弱关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我试图写它,而不使其弱,似乎没有泄漏。所以也许这个问题已经不再需要了。

Update: I tried writing it without making it weak, and there doesn't seem to be a leak. So maybe the question is no longer necessary.

在Objective-C ARC中,要使用自身内部的闭包,块不能捕获一个强的引用本身,或者它将是一个保持循环,所以,你可以使闭包捕获一个弱引用本身,如下:

In Objective-C ARC, when you want to have a closure be able to use itself inside of the closure, the block cannot capture a strong reference to itself, or it will be a retain cycle, so instead you can make the closure capture a weak reference to itself, like so:

// This is a simplified example, but there are real uses of recursive closures
int (^fib)(int);
__block __weak int (^weak_fib)(int);
weak_fib = fib = ^(int n) {
  if (n < 2)
    return n;
  else
    return weak_fib(n-1) + weak_fib(n-2);
};

我试图将它翻译成Swift:

I tried to translate this to Swift:

var fib: (Int -> Int)?
fib = { [weak fib] (n: Int) in // 'weak' cannot be applied to non-class type 'Int -> Int'
  if n < 2 {
    return n
  } else {
    return fib!(n-1) + fib!(n-2)
  }
}

但是,Swift编译器不允许我声明一个被弱捕获的函数(弱'不能应用于非类类型'Int - > Int')。 [unowned fib] 也不起作用('unowned'不能应用于非类型'(Int - > Int)? )。

However, the Swift compiler won't allow me to declare a function to be captured weakly ('weak' cannot be applied to non-class type 'Int -> Int'). [unowned fib] also doesn't work ('unowned' cannot be applied to non-class type '(Int -> Int)?').

我知道函数不是Swift中的类类型。但是,它们是引用类型,它们确实参与引用计数。因此,不应该有一种方法使它们成为弱的或者无用的引用?

I know that functions are not class types in Swift. However, they are reference types and they do participate in reference counting. Therefore, shouldn't there be a way to make them weak or unowned references?

我如何在Swift中写一个没有保留循环的递归闭包?

How would I write a recursive closure in Swift that doesn't have a retain cycle?

推荐答案

看起来这是不可能的;您可能希望提交错误

Looks like this isn't possible at the moment; you might want to file a bug.

但您可以使用实际的 func 以实现相同的事情:

But you can use an actual function to achieve the same thing:

func fib(n: Int) -> Int {
    if n < 2 {
        return n
    } else {
        return fib(n-1) + fib(n-2)
    }
}

fib(10) // 55

计算机科学有趣的时间!更直接地翻译您的代码,我们可以使用 Z组合器,借助Swift的内置curry函数定义:

Computer science fun time! For a more direct translation of your code, we can use the Z combinator, with help from Swift's built-in curried function definitions:

func Z<T, U>(f: (T -> U, T) -> U)(x: T) -> U {
    return f(Z(f), x)
}

let fib = Z { (fib: Int -> Int, n: Int) in
    if n < 2 {
        return n
    } else {
        return fib(n-1) + fib(n-2)
    }
}

fib(x: 10) // 55

// (Note the name 'x' should not be required here.
//  It seems seems to be a bug in Beta 3, since the curried function in the
//  Swift guide doesn't work as advertised either.)

这篇关于在Swift中不能弱关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆