当前位置: 首页 > 面试题库 >

在Swift中使自身变得脆弱

乐正意智
2023-03-14
问题内容

我有一个Swift类,需要存储自己的方法表。不幸的是,这导致了一个引用周期,因为它的表self通过其存储的方法保留了对它的引用。

以下示例泄漏代码:

typealias Callback = ()->()

class CycleInducingClass : NSObject {
    var myCallbacks = [Callback]()

    override init() {
        super.init()
        myCallbacks.append(myInternalFunction)
    }

    func myInternalFunction() {
        NSLog("lolol: %d", self.myCallbacks.count)
    }
}

到目前为止,我发现的唯一解决方案是改为执行此操作:

myCallbacks.append({[unowned self] in self.myInternalFunction()})

这很丑陋,而且容易出错。还有更好的主意吗?是否有一些使函数引用本身变弱的技巧?即使myCallbacks类型的数组myCallbacks : [WeakCallback]()或什么?据我所知,我什至无法weaken在上述丑陋的封闭包装上构建作为语法糖的便捷功能。


问题答案:

您当然可以为此构建一个函数。我不知道它是否可以使它变得更好,但是它不容易出错。

func methodPointer<T: AnyObject>(obj: T, method: (T) -> () -> Void) -> (() -> Void) {
  return { [unowned obj] in method(obj)() }
}
...
myCallbacks.append(methodPointer(self, CycleInducingClass.myInternalFunction))

或者,您可以将回调作为方法指针进行管理:

typealias Callback = (CycleInducingClass) -> () -> Void
...
myCallbacks.append(CycleInducingClass.myInternalFunction)

在这种情况下,您需要self在呼叫他们时通过(如果您实际上不做很多事情,那可能会很好):

self.myCallbacks[0](self)()

所有这些都是基于这样一个事实,即T带有签名的类型方法(input) -> (output)等同于带有签名的函数(T) -> (input) -> (output)

万一您好奇(我曾经),在这种情况下,覆盖可以正常工作。因此,如果您子类化CycleInducingClass并重写myInternalFunction,则会调用正确的版本。(这实际上让我感到有些惊讶,但我还不知道它为什么起作用,但确实如此。)

编辑:这是答案:https :
//devforums.apple.com/message/1036509#1036509



 类似资料:
  • 脆皮是一款很好玩的挂机类文字游戏。在这个世界我们要捕捉驯养一种名为 trimp(咱们称之为:脆皮)的生物,让它们繁衍,为你采集食物、树木、金属甚至研发科技点数。 也有地图可以战斗,不过派去战斗是 trimp 而不是我们的人物。 战斗途中可以获得资源和不少解锁,主要为各种升级解锁和trimp们的装备解锁。

  • 问题内容: 我希望能够以原子方式递增计数器,而我却找不到有关如何执行此操作的参考。 根据评论添加更多信息: 您正在使用GCD吗?不,我没有使用GCD。必须使用队列系统来增加数字似乎过大了。 请 您理解基本的线程安全?是的,否则我不会问原子增量的问题。 这个变量是局部变量吗?没有。 它是实例级别吗? 是的,它应该是单个实例的一部分。 我想做这样的事情: 问题答案: 来自低级并发API: OSAtom

  • 问题内容: 在Objective-C中,我在构建设置->代码中使用的其他C标志中设置了一堆编译器标志。例如: 标志=> -DPortNumber = 1 在代码中,我能够通过 这在Swift中不起作用,而且我找不到答案。 问题答案: C编译器的标志定义了预处理器宏。Swift中没有预处理器宏。因此,如果您要执行以下操作: …你不能。Swift旨在使源代码在编译之前在语法上完整。如果您可以在构建时关

  • 问题内容: 在我的iOS应用程序中,我想使用WKWebView在应用程序中包装外部URL 。此URL需要基本身份验证(它需要用户和密码凭据,如以下屏幕截图所示)。 经过一番调查,我尝试使用 didReceiveAuthenticationChallengemethod来启用自动 登录,因此我不了解它的工作原理。 这是我的代码。 I’m facing with this exception: If

  • 问题内容: 我想实现一个单独的ErrorHandler类,该类在某些事件上显示错误消息。该类的行为应从其他不同的类中调用。发生错误时,它将有一个as输出。此AlertView的显示应始终位于顶部。因此,无论从何处引发错误,最顶层的viewController都应显示AlertMessage(例如,当异步后台进程失败时,无论在前台显示什么视图,我都将收到一条错误消息)。 我发现一些要点似乎可以解决我

  • 问题内容: 尽管使用了组合而不是继承? 如果是这样,在语言级别上有什么解决方案吗? 问题答案: 正如VonC所写,但我想指出一点。 所述脆弱的基类问题通常归咎于虚拟方法( 方法动态调度 -这意味着如果方法可重写的,其具有的实际实现在这样的重写方法只能在运行时被决定的情况下被调用)。 为什么这是个问题?您有一个类,向其中添加了一些方法,如果进行了调用,则不能保证您所编写的将被调用,并且不能保证子类的