How to run code when a static instance is initialized? - ios

I'm using this pattern:
open class CoreDataHub {
public static let sharedInstance = CoreDataHub()
open class func getThing() -> String {
return "hello world"
}
init() {
sharedInstance.getThing()
}
}
But I get the following error:
Static member 'getThing' cannot be used on instance of type 'CoreDataHub'
My goal is to run some code...namely call getThing() when the sharedInstance is initialized. Any ideas? Thank you

You are getting
Static member 'getThing' cannot be used on instance of type 'CoreDataHub'
because, you are called getThing() static method using sharedInstance object.
Use CoreDataHub.getThing() instead of sharedInstance.getThing()
public static let sharedInstance = CoreDataHub()
init() {
let value = CoreDataHub.getThing()
}

Related

How to prevent lazy loading of static variables in Swift

I wrote a Swift utility class in which I define several static methods and a private static constant. However, I wish this constant to be loaded immediately after the class is referenced for the first time, as opposed to lazily. The only thing I can think of doing is to reference the static constant in every single static function like this:
private static let myObserver: Observer = {
let observer = Observer(actionToPerform: foo1)
SomeOtherClass.register(observer)
return observer
}()
static func foo1() {
_ = myObserver
...
}
static func foo2() {
_ = myObserver
...
}
static func foo3() {
_ = myObserver
...
}
//even more of a hassle:
static let myIntConstant: Int = {
_ = myObserver
return 5
} ()
.
.
.
However, that solution looks pretty ugly. Is there a cleaner way? Some sort of class initialization callback I can use?
Ok, I seem to have found a workable solution to my own question.
Ensure that the class is a subclass of NSObject.
Insert the following code:
override class func initialize() {
_ = myObserver
}
After doing this, the static constant is loaded immediately after the class is referenced, as desired.
Of course, this approach is limited by the fact that the class must be a subclass of NSObject, which may not be possible for all such classes. Any other potential drawbacks to this approach would be welcomed!

Private static variable is accessible in different classes?

I declared a private static variable in one class. In the other file I could see them in the auto-complete. Is it some kind of a bug?
class Apple {
private static var name = "Apple"
}
In different file,
class Steve {
func call() {
// I could autocomplete, but it is not accessible as it says no member with the name
let name = Apple.name
}
}
After compile you can see auto-complete.

What is the best practice to prevent an instance from init() in a Singleton class in Swift

I learned from Using Swift with Cocoa and Objective-C that a singleton can be created like this:
class Singleton {
static let sharedInstance = Singleton()
}
But as I learned, we should also prevent an instance created from the constructor. Creating an instance of the class Singleton outside the class scope, like the statement below, should be prevented:
let inst = Singleton()
So, could I do just like this:
class Singleton {
static let sharedInstance = Singleton()
private init() {}
}
Or, is there any better practice?
The way that you have suggested is the way that I always implemented it.
public class Singleton
{
static public let sharedInstance = Singleton();
private init()
{
}
}
It's the cleanest solution for a Singleton pattern that I've ever found. Now that in Swift 2 you can specify accessibility it does actually prevent you from calling something like:
var mySingleton = Singleton();
Doing so results in a compile time error:
'Singleton' cannot be constructed because it has no accessible initializers
private let singletonInstance = Singleton()
final class Singleton: NSObject {
static func getInstance() -> Singleton {
return singletonInstance
}
}
Try that. Nothing is wrong in using global object here, it is created lazily (on first call).

Singleton in one line on Swift 2.0

Please help me with Swift,
I need singleton with can inheritance.
I can do like this
class A {
var defaultPort: Int
required init() {
self.defaultPort = 404
}
class var defaultClient: A {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: A? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = self.init()
}
return Static.instance!
}
}
but in swift 2.0 we can do like this
static let defaultClient = A() //self.init()
but it creates an instance of the class A any way.
How i can use like this self.init()
static let defaultClient = self.init()
in order to be able to inherit
UPD
best way for now
class A {
class func defaultClient() -> Self {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: A? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = self.init()
}
return instance(Static.instance, asType: self)
}
}
here we need helper as
func instance<T>(instance: Any, asType type: T.Type) -> T {
let reurnValue = instance as! T
return reurnValue
}
because another way cast A to Self not exist, for now.
p.s. crazy swift way!
why i can not do instance as! Self
Your question isn't very clear. You're looking for something like the class constant solution posted in this answer, but which automatically uses "my own class" instead of explicitly creating an instance of a specific class... right?
That is, you want to turn this:
class Singleton {
static let sharedInstance = Singleton()
}
into this:
class Singleton {
static let sharedInstance = SomeMagicThing()
}
class SingletonSubclass {}
where SomeMagicThing automatically creates a Singleton instance when you call Singleton.sharedInstance, and a SingletonSubclass instance when you call SingletonSubclass.sharedInstance. Correct?
Sorry, that can't be done (as of Swift 2.1).
Part of your issue is that static and class mean two different things. The static modifier means that the declaration it modifies is associated only with a specific type declaration. So, the Singleton type owns a pointer to a specific object -- its subclasses don't inherit that pointer. (And if they did, would it point to the same object or a subclass-specific one?)
If you could create a class var or class let, that'd (in theory) give you the kind of dispatch/inheritance you want. But trying that gives you an error (emphasis mine):
class stored properties not yet supported in classes; did you mean static?
So it sounds like this sort of thing might show up someday.
Of course, the other side of the problem is finding a way to dynamically refer to the "current" type responsible for executing some statement. In the context of an instance method, you have self.dynamicType for such things... but there's no equivalent for classes. (Self is a type constraint, not an actual type.) This is a side effect of the type system in Swift being much more strict and static than that of Objective-C (for example, metatypes aren't just a special flavor of otherwise normal objects). File a bug if you'd like to see a change to that effect?

Why does the suggested Swift singleton implementation use a struct?

The commonly accepted Singleton pattern for Swift uses a Struct inside a class variable/type property.
Instead of:
class MySingleton {
class var sharedInstance: MySingleton {
struct Singleton {
static let instance = MySingleton()
}
return Singleton.instance
}
}
Why do we not just do:
class MySingleton {
class var sharedInstance: MySingleton {
let instance = MySingleton()
return instance
}
}
Apologies if this is a very stupid question. But don't both leverage the thread-safety of constants and let?
with your implementation, the 'sharedInstance' is not a singleton cause each time it gets called, it creates new instance of MySingleton. And, to create a static variable, you have to put it in struct o enums, otherwise, you will get compiler error
from Swift 1.2 & up you should use - see Apple's ref doc here :
class DeathStarSuperlaser {
static let sharedInstance = DeathStarSuperlaser()
private init() {
// Private initialization to ensure just one instance is created.
}
}

Resources