Here is my settings.swift file :
import Foundation
class Settings {
func setDefaultSettings() {
}
}
I would like to access the function in AppDelegate didFinishLaunchingWithOptions. I've tried calling
Settings.setDefaultSettings() but it didn't work.
You have two ways to make this work:
1.Initialise object of Settings class
Settings().setDefaultSettings()
or
let settings = Settings()
settings.setDefaultSettings()
2.Make the function static
static func setDefaultSettings(){...}
in this case you can call it your way
Settings.setDefaultSettings()
Method can be defined in two ways : Instance method and class Methods
You have declared the method as Instance method, which can accessible through the instance of the class. So, to access the methods needs instance of the class, which can be created as
let settingObj = Settings()
settingObj.setDefaultSettings()
-------------------------------------------------
//Combined statement
Settings().setDefaultSettings()
and class method can be written using the keyword static or class. They can be access by the class name itself. Please see the example below
class Settings {
class func setDefaultSettings()
{
print("Default Settings")
}
}
Now you can call the method directly by the class name
Settings.setDefaultSettings()
You can access this method as follow
1) Create one Class of NSObject as follow.(GLOBAL.swift)
class GLOBAL : NSObject {
//sharedInstance
static let sharedInstance = GLOBAL()
}
2) Define your method here.
class GLOBAL : NSObject {
//sharedInstance
static let sharedInstance = GLOBAL()
func setDefaultSettings() {
}
}
3) Use above method as follow.
GLOBAL.sharedInstance.setDefaultSettings()
You can also use this setDefaultSettings() in setting class and also any other class.
Related
There is a class declared as singleton in Swift. An instance called A is declared inside this singleton class.
Originally, there is only one instance of this A in memory.
Is there any way to make multiple instances of this A instance in a singleton class?
A class
protocol ADelegate{
func onSuccess()
func onFail()
}
// I want to create multiple instances of this
class A{
var delegate: ADelegate!
// ...
func requestCallback(){
//...
// success response
delegate.onSuccess()
}
}
class ModuleA: ADelegate{
var aInstance = A(delegate: self)
func req(){
aInstance.requestCallback()
}
func onSuccess(){
// ModuleA do something
}
func onFail(){
}
}
class ModuleB: ADelegate{
var aInstance = A(delegate: self)
// ModuleB do something
}
singleton class(Main)
class Main{
static var shared = Main()
// Using ModuleA, ModuleB
}
If you want to make multiple instances of class A in memory then it is will not be called as singleton class. This will contradict the design pattern concept of singleton. If you want multiple instance of A then make the class as normal class. But singleton class can have only one instance.
I have been trying to convert a singleton class to generic. Since swift doesn't support stored property in generic class Singleton could not be implemented. I tried all the possible solutions that I know but nothing works. Other Stackoverflow answers related to this topic doesn't help either. Can someone help me to get on the right path, please? Thanks in advance.
I have added the sample code below.
class SingleTonClass<T: Equatable & RawRepresentable>: NSObject where T.RawValue == String {
private var catlog: CatlogModelClass<T>?
private var catlogArray = [CatlogModelClass<T>]()
**// This stored property Now has to be changed to support Generic**
private static var shared : SingleTonClass = {
return SingleTonClass()
}()
// Accessor for Singleton
static func sharedInstance() -> SingleTonClass {
return shared
}
private override init () {}
}
If you want it to be non-singleton, you need to create a public constructor.
You should pass in the catalog and catalogArray into the constructor and initialize self.catalog and self.catalogArray. You then need to remove the static shared instance of the class, because your new setup would require you to create an instance of it.
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).
When I create two classes like so:
class Example
{
}
class OtherExample
{
init() {
println("created")
}
}
var instance = Example()
var otherInstance = OtherExample()
Both seem to create usable instances, so I'm wondering what the difference is in Swift if you don't provide an init method, and yet you initialise as above?
I did think it probably called the superclass init automatically, however since both of these objects don't inherit from NSObject, they don't have super classes do they?!
Also is there a need to class super.init() in the otherExample?
You only need super.init() if your class inherits from another class.
class Example {
func sayHi() {
print("hi")
}
}
class OtherExample: Example {
override init() {
super.init()
print("created")
}
}
var instance = Example()
instance.sayHi()
// hi
var otherInstance = OtherExample()
otherInstance.sayHi()
// created
// hi
class example{
var example:Int = 0
}
class anotherExample{
init(example:Int){
self.example = example
}
var example:Int
}
example()
anotherExample(0)
You can have not initialized variables in a class with an initializer, if you don’t have any initializer you will need to set a value in the class
Both will be able to change their example value but only anotherExample will have a value that can be set.
In my test playground I was unable to use super.init() in the classes (since they don’t have any superclasses to init to/from)
I'm looking for behavior similar to Objective-C's +(void)initialize class method, in that the method is called once when the class is initialized, and never again thereafter.
A simple class init () {} in a class closure would be really sleek! And obviously when we get to use "class vars" instead of "static vars in a struct closure", this will all match really well!
If you have an Objective-C class, it's easiest to just override +initialize. However, make sure subclasses of your class also override +initialize or else your class's +initialize may get called more than once! If you want, you can use dispatch_once() (mentioned below) to safeguard against multiple calls.
class MyView : UIView {
override class func initialize () {
// Do stuff
}
}
If you have a Swift class, the best you can get is dispatch_once() inside the init() statement.
private var once = dispatch_once_t()
class MyObject {
init () {
dispatch_once(&once) {
// Do stuff
}
}
}
This solution differs from +initialize (which is called the first time an Objective-C class is messaged) and thus isn't a true answer to the question. But it works good enough, IMO.
There is no type initializer in Swift.
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
You could use a type property which default value is a closure. So the code in the closure would be executed when the type property (or class variable) is set.
class FirstClass {
class var someProperty = {
// you can init the class member with anything you like or perform any code
return SomeType
}()
}
But class stored properties not yet supported (tested in Xcode 8).
One answer is to use static, it is the same as class final.
Good link for that is
Setting a Default Property Value with a Closure or Function
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
Code example:
class FirstClass {
static let someProperty = {
() -> [Bool] in
var temporaryBoard = [Bool]()
var isBlack = false
for i in 1...8 {
for j in 1...8 {
temporaryBoard.append(isBlack)
isBlack = !isBlack
}
isBlack = !isBlack
}
print("setting default property value with a closure")
return temporaryBoard
}()
}
print("start")
FirstClass.someProperty
Prints
start
setting default property value with a closure
So it is lazy evaluated.
For #objc classes, class func initialize() definitely works, since +initialize is implemented by the Objective-C runtime. But for "native" Swift classes, you'll have to see the other answers.
You can use stored type properties instead of initialize method.
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
}
But since stored types properties are actually lazily initialized on their first access, you will need refer them somewhere. You can do this with ordinary stored property:
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
private let initializer: Void = SomeClass.initializer
}
#aleclarson nailed it, but as of recent Swift 4 you cannot directly override initialize. You still can achieve it with Objective-C and categories for classes inheriting from NSObject with a class / static swiftyInitialize method, which gets invoked from Objective-C in MyClass.m, which you include in compile sources alongside MyClass.swift:
# MyView.swift
import Foundation
public class MyView: UIView
{
#objc public static func swiftyInitialize() {
Swift.print("Rock 'n' roll!")
}
}
# MyView.m
#import "MyProject-Swift.h"
#implementation MyView (private)
+ (void)initialize { [self swiftyInitialize]; }
#end
If your class cannot inherit from NSObject and using +load instead of +initialize is a suitable fit, you can do something like this:
# MyClass.swift
import Foundation
public class MyClass
{
public static func load() {
Swift.print("Rock 'n' roll!")
}
}
public class MyClassObjC: NSObject
{
#objc public static func swiftyLoad() {
MyClass.load()
}
}
# MyClass.m
#import "MyProject-Swift.h"
#implementation MyClassObjC (private)
+ (void)load { [self swiftyLoad]; }
#end
There are couple of gotchas, especially when using this approach in static libraries, check out the complete post on Medium for details! ✌️
I can't find any valid use case to have something like +[initialize] in Swift. Maybe this explains way it does not exist
Why do we need +[initialize] in ObjC?
To initialize some global variable
static NSArray *array;
+ (void)initialize {
array = #[1,2,3];
}
which in Swift
struct Foo {
static let array = [1,2,3]
}
To do some hack
+ (void)initialize {
swizzle_methodImplementation()
}
which is not supported by Swift (I can't figure out how to do it for pure Swift class/struct/enum)