Why does my @lazy property crash, but if I make it non lazy it works?
After some trial, I found something quite odd.
First of all, if we wrap the var inside a class, it simply works:
class RegionManager {
@lazy var enteredRegions = Array<String>()
}
In AppDelegate
, I declared a @lazy var regManager = RegionManager()
.
Then, in application:didFinishLaunching:
, I modify and use the value, it works without spitting a word:
regManager.enteredRegions.append("New!")
println("Regions: \(regManager.enteredRegions)") // Regions: [New!]
After this, I tried to change to some native values, for example, String
, Int
and so on, they all fail.
So, my guess is that this strange behaviour is actually a bug of the compiler itself, it may be rooted in some optimization for native types, maybe there's a inner pool or what that apple doesn't tell us.
Is there a way to tell if a lazy var has been initialized?
lazy
is just a convenience wrapper around one specific lazy-instantiation pattern (and one that is only moderately useful). If you want your own pattern, don't use lazy; just build it yourself.
private var _foo: NSViewController? = nil
var foo: NSViewController {
if let foo = _foo {
return foo
}
let foo = NSViewController()
foo.representedObject = self.representedObject
_foo = foo
return foo
}
// This can be private or public, as you like (or you don't technically need it)
var isFooLoaded: Bool {
return _foo != nil
}
override var representedObject: Any? {
didSet {
if !isFooLoaded {
foo.representedObject = representedObject
}
}
}
This is designed to follow the isViewLoaded
pattern, which addresses the same basic problem.
Lazy module variables--can it be done?
You can't do it with modules, but you can disguise a class "as if" it was a module, e.g., in itun.py
, code...:
import sys
class _Sneaky(object):
def __init__(self):
self.download = None
@property
def DOWNLOAD_PATH(self):
if not self.download:
self.download = heavyComputations()
return self.download
def __getattr__(self, name):
return globals()[name]
# other parts of itun that you WANT to code in
# module-ish ways
sys.modules[__name__] = _Sneaky()
Now anybody can import itun
... and get in fact your itun._Sneaky()
instance. The __getattr__
is there to let you access anything else in itun.py
that may be more convenient for you to code as a top-level module object, than inside _Sneaky
!_)
Related Topics
Unsafemutablepointer<Cftyperef> in Swift 3
Why Specify [Unowned Self] in Blocks Where You Depend on Self Being There
Uiimagepickercontroller Navigation Bar Tint Color Not Working with iOS 13
How to Cast Generic Number Type 'T' to Cgfloat
Trouble with Non-Escaping Closures in Swift 3
Swift 2.2, Contains Method Not Working
Swift Error Comparing Two Arrays of Optionals
Swiftui Behavior of .Frame(Height: Nil)
How to Add Openssl to a Swift Project
Swift. Declaring Private Functions in Internal Protocol
How to Handle Menu Button Action in Tvos Remote
Changing the Color of the Icons in a Uitextfield Inside a Uisearchbar