【问题标题】:Why does my @lazy property crash, but if I make it non lazy it works?为什么我的@lazy 属性会崩溃,但如果我让它非懒惰它会起作用?
【发布时间】:2014-06-04 09:28:40
【问题描述】:

我对惰性属性有疑问。我以为我得到了它们,但也许我没有/也许这是一个错误

我的班级中有一个惰性数组

@lazy var enteredRegions = Array<String>()

现在

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool

我有

 self.enteredRegions.append(clRegion!.identifier);

这会因 EXC_BAD_ACCESS 严重崩溃。

现在如果我删除 @lazy:

    var enteredRegions = Array<String>()

所有作品

所以..这是怎么回事? :D 我的理解是self.enteredRegions 无论如何都会创建它

(我使用 UIWindow 和 CLLocationManager 执行此操作,并且按我的想法工作)

【问题讨论】:

  • @lazy 用于昂贵的操作,因此在调用属性之前不会运行。创建数组并不是一项昂贵的操作,因此无论如何您都不应该需要 @lazy。此外,在我的所有测试中,@lazy 仅适用于类。
  • @AlexReynolds 听起来很合理,但要么不应该被允许,要么不应该崩溃
  • 是的,但这可能是保留计数问题。所以它可能是允许的,但由于保留计数没有增加,它被释放,因此访问不正确。这也不是@lazy 属性的目的。阵列没有什么是昂贵的。由于内存管理和运行时,许多导致崩溃的事情都是允许的
  • @AlexReynolds 这是懒惰的一种用途,但还有其他用途。 Apple 的文档说明了多种用途:“当属性的初始值依赖于外部因素时,惰性属性很有用,这些因素的值在实例初始化完成后才知道。当属性的初始值需要复杂时,惰性属性也很有用或计算量大的设置,除非需要,否则不应执行”。

标签: swift


【解决方案1】:

经过一番尝试,我发现了一些很奇怪的东西。

首先,如果我们将 var 包装在一个类中,它就可以正常工作:

class RegionManager {
    @lazy var enteredRegions = Array<String>()
}

AppDelegate 中,我声明了@lazy var regManager = RegionManager()

然后,在application:didFinishLaunching:中,我修改并使用了该值,它一言不发:

regManager.enteredRegions.append("New!")
println("Regions: \(regManager.enteredRegions)") // Regions: [New!]

在这之后,我尝试更改为一些native值,例如StringInt等等,都失败了。

所以,我的猜测是这种奇怪的行为实际上是编译器本身的一个错误,它可能源于对 native 类型的一些优化,也许有一个内部池或者那个苹果没有的东西'告诉我们。

【讨论】:

    猜你喜欢
    • 2011-08-08
    • 2016-08-06
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多