我有一个Objective-C单身如下:
@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.
}
在GUI代码中的多个位置调用它:
[[MyModel model] someMethod];
因此,模型将被创建,因为GUI的任何部分都会首先引用它。
我不确定如何通过Swift中的[[MyModel model] someMethod]实现相应的访问类,因为使用Swift的所有示例都涉及使用初始化程序创建对象以及将Objective C类方法代码转换为当方法没有参数时,Swift初始化代码存在问题,它无法正常工作。
答案 0 :(得分:11)
UPDATE ++++++++++
只有在使用从类名后缀派生的名称命名单例方法时,才需要使用下面的解决方法,即OPs问题方法名称是模型,类名为MyModel。
如果将方法重命名为singleton,则可以从Swift中调用它:
let m = MyModel.singleton()
+++++++++++
我不知道这是好/坏的做法,但是当通过添加虚拟init方法没有参数时,我能够解决初始化程序转换无法正常工作的问题。因此,使用其他答案中的代码作为示例:
@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)
上面的代码没有调用thing方法,但是thingWithFoo:bar:方法是。
但是如果它改为this,那么现在将调用thing方法:
@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)
答案 1 :(得分:6)
如果Swift编译器错误地将方法识别为类工厂方法,则可以使用NS_SWIFT_NAME宏,传递方法的Swift签名以正确导入它。例如:
+ (MyModel*)model NS_SWIFT_NAME(log());
所以,你的方法应该是这样的:
This is a crawling bug that we've now implemented handling for.
We are running a script that will check for queued scheduled crawls every hour
and start them if they are not running.
答案 2 :(得分:3)
完全按照编译器警告的要求进行操作:
MyModel().someMethod()
请继续阅读以了解原因......
Swift自动识别初始化器和便捷构造器的ObjC约定。如果你有一个类似这样的类:
@interface XYZThing : NSObject
+ (instancetype)thing;
+ (instancetype)thingWithFoo:(int)foo bar:(int)bar;
@end
...然后,当Swift将它们转换为初始值设定项时,它忽略了方法名称的一部分,即该类的通用名称(Thing
/ thing
),移动选择器的一部分,它将参数引用为参数标签,并删除连接这些部分的所有介词。所以初始化器声明在Swift中看起来像这样:
class XYZThing: NSObject [
init()
init(foo: Int, bar: Int)
}
你构建这样的对象:
let thing = XYZThing()
let otherThing = XYZThing(foo:3, bar:7)
后续:因为像+[XYZThing thing]
这样的类方法被ObjC to Swift翻译器处理为初始化器(即使它现在似乎没有完全起作用),这种命名模式对于单身。单例检索方法不应该是初始化器,因为初始化器总是创建一个新实例。
单例检索方法应该具有一个不以该类的通用名开头的名称;例如+sharedThing
,+defaultThing
,+oneThingToRuleThemAll
等