简体   繁体   English

如何使用ARC手动保留在Swift中?

[英]How do I manually retain in Swift with ARC?

I'm using Swift 3 with ARC in an iOS app, and I want to manually retain an object. 我在iOS应用程序中将Swift 3与ARC配合使用,我想手动保留一个对象。

I tried object.retain() but Xcode says that it's unavailable in ARC mode. 我尝试了object.retain(),但是Xcode表示它在ARC模式下不可用。 Is there an alternative way to do this, to tell Xcode I know what I'm doing? 有没有另一种方法可以告诉Xcode我知道我在做什么呢?


Long Version: 长版:

I have a LocationTracker class that registers itself as the delegate of a CLLocationManager. 我有一个LocationTracker类,它将自己注册为CLLocationManager的委托。 When the user's location changes, it updates a static variable named location. 当用户的位置更改时,它将更新名为location的静态变量。 Other parts of my code that need the location access this static variable, without having or needing a reference to the LocationTracker instance. 我代码中需要位置的其他部分访问此静态变量,而无需或不需要引用LocationTracker实例。

The problem with this design is that delegates aren't retained, so the LocationTracker is deallocated by the time the CLLocationManager sends a message to it, causing a crash. 这种设计的问题在于,不保留委托,因此在CLLocationManager向其发送消息之前,LocationTracker已被释放。

I would like to manually increment the refcount of the LocationTracker before setting it as a delegate. 我想手动将LocationTracker的refcount设置为委托之前。 The object will never be deallocated anyway, since the location should be monitored as long as the app is running. 该对象将永远不会被释放,因为只要应用程序正在运行,就应该监视该位置。

I found a workaround, which is to have a static variable 'instance' that keeps a reference to the LocationTracker. 我找到了一种解决方法,即拥有一个静态变量'instance'来保留对LocationTracker的引用。 I consider this design inelegant, since I'm never going to use the 'instance' variable. 我认为这种设计不雅致,因为我永远不会使用'instance'变量。 Can I get rid of it and explicitly increment the refcount? 我可以摆脱它并显式增加refcount吗?

This question is not a duplicate, as was claimed, since the other question is about Objective-C, while this one is about Swift. 正如所声称的,这个问题不是重复的,因为另一个问题是关于Objective-C的,而这个问题是关于Swift的。

This is easily done with withExtendedLifetime(_:_:) function. 使用withExtendedLifetime(_:_:)函数可以轻松完成此操作。 From the documentation: 从文档中:

Evaluates a closure while ensuring that the given instance is not destroyed before the closure returns. 在评估闭包的同时确保闭包返回之前不破坏给定实例。

Cheers! 干杯!

The solution turned out to be to re-enable retain() and release(): 原来的解决方案是重新启用keep()和release():

extension NSObjectProtocol {
  /// Same as retain(), which the compiler no longer lets us call:
  @discardableResult
  func retainMe() -> Self {
    _ = Unmanaged.passRetained(self)
    return self
  }

  /// Same as autorelease(), which the compiler no longer lets us call.
  ///
  /// This function does an autorelease() rather than release() to give you more flexibility.
  @discardableResult
  func releaseMe() -> Self {
    _ = Unmanaged.passUnretained(self).autorelease()
    return self
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM