Hard to say without full code, but the following code compiles just fine in
Xcode 8:
class FloorPlatonicGeometryAndMaterial {
init(modelDirectory: NSURL) throws {
/// ...
}
}
class PlatonicPieceOfFurniture {
internal var modelDirectoryURL: URL
var floorGeometryAndMaterial: FloorPlatonicGeometryAndMaterial {
return self.floorGeometryAndMaterialBacking!
}
private lazy var floorGeometryAndMaterialBacking:
FloorPlatonicGeometryAndMaterial? =
try!
FloorPlatonicGeometryAndMaterial(modelDirectory: self.modelDirectoryURL)
init(modelDirectoryURL: URL) {
self.modelDirectoryURL = modelDirectoryURL
/// ...
}
}
All lazy initialization pretty much uses dispatch_once. Also remember, that
your code can be as followed:
private lazy var stringValue: String? = {
var str = self.description
str += "\n"
...
return str
}()
lazy var initialization doesn't have to be a one-liner, but can be an applied
closure.
> On Jun 16, 2016, at 7:48 PM, William Shipley via swift-evolution
> <[email protected]> wrote:
>
> I may be missing something, but I don’t understand how to get the behavior of
> dispatch_once() without a bunch more code in cases in which I was using it to
> initialize “lazy-ish" instance variables.
>
> public class PlatonicPieceOfFurniture {
>
> internal var modelDirectoryURL: URL
>
> /* … */
>
> public var floorGeometryAndMaterial: FloorPlatonicGeometryAndMaterial {
> dispatch_once(&dispatchOnceLoadGeometriesAndMaterials) {
> self.floorGeometryAndMaterialBacking = try!
> FloorPlatonicGeometryAndMaterial(modelDirectory: self.modelDirectoryURL)
> }
> return floorGeometryAndMaterialBacking!
> }
> private var floorGeometryAndMaterialBacking:
> FloorPlatonicGeometryAndMaterial?
> private var dispatchOnceLoadGeometriesAndMaterials: dispatch_once_t = 0
>
> }
>
> Note that ‘floorGeometryAndMaterial' isn’t a global, and that it requires
> ‘modelDirectoryURL’ as input when it is lazily initialized, so I can't just
> do:
>
> public lazy var floorGeometryAndMaterial:
> FloorPlatonicGeometryAndMaterial? = try!
> FloorPlatonicGeometryAndMaterial(modelDirectory: modelDirectoryURL)
>
> Because that throws a “instance member ‘modelDirectoryURL’ cannot be used on
> type ‘PlatonicPieceOfFurniture’” error in Xcode. (Also, honestly, I don’t see
> much utility in lazy instance variables in Swift, since I can’t use any state
> from the current instance to initialize them, so they’re usually no better
> than static variables — I don’t think I’ve ever used them, despite trying a
> bunch.)
>
> Also this needs to be thread-safe, and loading the backing is very slow so we
> really don’t want to ever accidentally do it twice (although it would be safe
> to do so in my code), so I can’t just check if
> ‘floorGeometryAndMaterialBacking’ is nil and load it up if it is.
>
>
> I could do an ugly version of this with semaphores and an extra flag, but it
> seems a lot cleaner with dispatch_once().
>
> Am I missing something obvious? The Swift 3 converter completely mangled my
> code into a static case which didn’t compile at all and couldn’t possibly
> work.
>
>
> -Wil Shipley
> Delicious Monster
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution