In all these cases, you have to provide the object with its delegate (or target) at initialization time. And that leads to a terrible head-scratcher. What do you do if you want to use one of these objects as a property, but also use
selfas the delegate?Swift won’t let you easily do this.
[…]
The point of the
lazyvariable is that it won’t be assigned until its needed. Which in turn means that it can’t be accessed untilselfexists, because otherwise there’s no way to access it. Therefore, it’salways OK to referenceselfwhen assigning alazyvariable.
I understand the reasoning behind Swift’srules for two-phase initialization and where you can accessself. But in practice they introduce extra work and code ugliness in order to prevent a class of problems that I don’t think I’ve ever had.lazy variables are the best solution I’ve found for the issue that Adamson mentions. In fact,lazy variables are pretty cool in general, although beware that their initialization isnot thread-safe.
The other main issue I run into with initialization is that youcan’t call helper methods before callingsuper.init(). This is not an issue in Objective-C because, there, calling[super init] is the first thing you do. But in Swift you have to initialize all of your properties before callingsuper.init(). Implicitly-unwrapped optionals are the obvious, easy solution. Otherwise, you would need to move helper code from instance methods to static functions or a separate helper object or, in some cases, completely restructure your code if you need to access state or functionality from the superclass.
Update (2017-08-31): One of the issues that neitherlazy nor IUOs solve is that you may end up needing to make the propertyvar instead oflet, even though you have no intention of modifying it once set. You can partially mitigate this by marking the propertyprivate(set). However, that adds yet more verbosity and doesn’t as obviously protect against concurrent access the waylet does.
Regardinglazy and concurrency,Heath Borders writes:
I just use another computed property that wraps the
lazy varin aDispatch.syncover a private queue, then I never touch thelazy var.
Update (2017-09-01): Another issue with IUOs is the way they work with type inference. If you assign an IUO to a temporary variable, the inferred type is an optional. This means that you have to either force unwrap when assigning to the temporary or at each use of the temporary. So the IUO has leaked outside of its class. One way around this is to create two properties in the class. The first is aprivate var of typeT!. The second is a computed property of typeT that returns the first property (implicitly) unwrapped. Then clients of the class can use the computed property and not have to deal with unwrapping.
Previously:
ConcurrencyLanguage DesignProgrammingSwift Programming Language
Black Friday
Blog
Archives
Tag Cloud
Top Posts
Recently Updated
RSS Feed ·Comments
Mastodon ·Twitter
Apple News
Trackback
Support this site viaPatreon.
Try my Mac apps: