I have an objective-C singleton as follows:
@interface MyModel : NSObject
+ (MyModel*) model;
...
+ (MyModel*) model
{
static MyModel *singlton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^ {
singlton = [[MyModel alloc] initSharedInstance];
});
return singlton;
}
- (MyModel*) initSharedInstance
{
self = [super init];
if (self)
etc.
}
Which gets called in multiple places within the GUI code as:
[[MyModel model] someMethod];
And therefore the model will get created as a consequence of whichever part of the GUI happens to reference it first.
I'm not sure how to implement the equivalent of accessing the class via [[MyModel model] someMethod] in Swift as all examples of using Swift involve creating an object using an initializer and when Objective C class method code is converted to Swift initializer code there is a problem with it not working when the method does not have parameters.
To use Swift classes in Obj-C you both need to #import "SingletonTest-Swift. h the generated header or forward declaration with @class MySwiftClass . Additionally the class needs to inherit from an Obj-C class like you have don here with NSObject or be marked with @objc to expose it.
In Swift, Singleton is a design pattern that ensures a class can have only one object. Such a class is called singleton class. An initializer allows us to instantiate an object of a class. And, making the initializer of a class restricts the object creation of the class from outside of the class.
A programmer cannot inherit the pure-singleton class. When you try to inherit any class in swift, you must call the constructor of the superclass.
What is a Singleton Class? A singleton class returns the same instance no matter how many times an application requests it. Unlike a regular class, A singleton object provides a global point of access to the resources of its class.
You can work with types declared in Swift from within the Objective-C code in your project by importing an Xcode-generated header file. This file is an Objective-C header that declares the Swift interfaces in your target, and you can think of it as an umbrella header for your Swift code.
When declarations in an Objective-C header file refer to a Swift class or protocol that comes from the same target, importing the generated header creates a cyclical reference. To avoid this, use a forward declaration of the Swift class or protocol to reference it in an Objective-C interface.
If you want to wrap a C [system] library and call it directly from Swift you can crete a brand new wrapper package with the help of the Swift Package Manager. To start you can use the swift package init --type system-module command, this will create a generic template project.
This setup also works with C, C++, Objective-C, Objective-C++ code. If you want to wrap a C [system] library and call it directly from Swift you can crete a brand new wrapper package with the help of the Swift Package Manager.
If the Swift compiler mistakenly identifies a method as a class factory method, you can use the NS_SWIFT_NAME macro, passing the Swift signature of the method to have it imported correctly. For example:
+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));
so,your method should be this:
+ (MyModel*)model NS_SWIFT_NAME(log());
UPDATE ++++++++++
The workaround below is only necessary if you name your singleton method with a name derived from the suffix of the class name i.e. the OPs question the method name is model and the class is called MyModel.
If the method is renamed to something like singleton then it is possible to call it from Swift just like this:
let m = MyModel.singleton()
+++++++++++
I don't know if this is good/bad practice but I was able to get around the problem with initializer conversion not working when there are no parameters by adding a dummy init method. So using the code from the other answer as an example:
@interface XYZThing : NSObject
+ (XYZThing*) thing;
+ (XYZThing*) thingWithFoo:(int)foo bar:(int)bar;
@end
@implementation XYZThing
+ (XYZThing*) thing
{
NSLog(@"This is not executed");
return nil;
}
+ (XYZThing*)thingWithFoo:(int)foo bar:(int)bar
{
NSLog(@"But this is");
return nil;
}
@end
...
let thing = XYZThing()
let otherThing = XYZThing(foo:3, bar:7)
With this code above the thing method is not called, but the thingWithFoo:bar: method is.
But if it is changed to this then now the thing method will get called:
@interface XYZThing : NSObject
+ (XYZThing*) init;
+ (XYZThing*) thing;
+ (XYZThing*) thingWithFoo:(int)foo bar:(int)bar;
@end
@implementation XYZThing
+ (XYZThing*) init
{
return nil;
}
+ (XYZThing*) thing
{
NSLog(@"Now this is executed");
return nil;
}
+ (XYZThing*)thingWithFoo:(int)foo bar:(int)bar
{
NSLog(@"And so is this");
return nil;
}
@end
...
let thing = XYZThing()
let otherThing = XYZThing(foo:3, bar:7)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With