【问题标题】:Using 'self' on RxSwift closures... What about instance methods as param?在 RxSwift 闭包上使用“self”......实例方法作为参数怎么样?
【发布时间】:2024-05-01 03:55:02
【问题描述】:

other stack overflow questions 中,强调捕获[weak self] 应该用于不属于该类的闭包,因为self 在闭包完成之前可能为零。当闭包由类本身拥有时,另一种选择是[unowned self]

我的问题是当我作为参数传递的函数是当前类的实例方法时,我是否需要使用[unowned self]

示例

import RxSwift

class Person {
    var name = "Default name"

    class func getPersons() -> Observable<Person> {
        // ...
    }


}

class MyController: UIViewController {
    let disposeBag = DisposeBag()

    // I know this right
    func unownedDisplayPeople() {

        Person.getPersons()
            .subscribeNext { [unowned self ] person in
                self.displayName(person)
            }
            .addDisposableToBag(disposeBag)
    }

    // But what about this?
    func whatAboutThisDisplayPeople() {

        Person.getPersons()
            .subscribeNext(displayName)
            .addDisposableToBag(disposeBag)
    }

    // Or this?
    func orThisDisplayPeople() {

        Person.getPersons()
            .subscribeNext(self.displayName)
            .addDisposableToBag(disposeBag)
    }

    func displayName(person: Person) {
        print("Person name is \(person.name)")
    }
}

如果我只是传递一个实例方法时仍然需要考虑引用计数,我该怎么做?我把[unowned self]放在哪里?或者当我刚刚通过实例方法时,它是否已经被认为是[unowned self]

【问题讨论】:

标签: memory swift2 rx-swift retain-cycle retaincount


【解决方案1】:

不幸的是,将实例方法传递给subscribeNext 保留self。更通用地说,存储对实例方法的引用会增加实例的保留计数。

let instance = ReferenceType()
print(CFGetRetainCount(instance)) // 1

let methodReference = instance.method
print(CFGetRetainCount(instance)) // 2

这里唯一的解决方案是做你在unownedDisplayPeople中所做的事情。

let instance = ReferenceType()
print(CFGetRetainCount(instance)) // 1

let methodReference = { [unowned instance] in instance.method() }
print(CFGetRetainCount(instance)) // 1

【讨论】:

  • 感谢您澄清这个 tomahh。我只是被语法困扰,因为它看起来一点也不漂亮。 :( 但我想我得凑合着用它来防止内存泄漏。
  • 是的,我也讨厌它。也许有一种方法我们可以创建一个subscribeNextsubscribeWeaklyNext 版本,它不会改变保留计数......
  • 所以,我在 swift 操场上摆弄了一下,然后撞到了墙上。 weak 不能进行闭包,因为它仅适用于类和类绑定协议。我猜 self 在函数调用(接受闭包)之前被捕获。似乎我们被这种“非最佳”语法所困扰:/
  • 补充阅读:blog.stablekernel.com/…
最近更新 更多