如何从 Swift 调用 Objective-C 单例? [英] How to call an Objective-C singleton from Swift?

查看:64
本文介绍了如何从 Swift 调用 Objective-C 单例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个objective-C单例如下:

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.
        }

在 GUI 代码中的多个地方被调用为:

Which gets called in multiple places within the GUI code as:

[[MyModel model] someMethod];

因此,无论 GUI 的哪个部分碰巧首先引用它,都会创建模型.

And therefore the model will get created as a consequence of whichever part of the GUI happens to reference it first.

我不确定如何在 Swift 中实现通过 [[MyModel 模型] someMethod] 访问类的等效方法,因为所有使用 Swift 的示例都涉及使用初始化程序创建对象,以及何时将 Objective C 类方法代码转换为Swift 初始化代码存在一个问题,当方法没有参数时它不起作用.

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.

推荐答案

UPDATE++++++++++++

UPDATE ++++++++++

仅当您使用从类名的后缀派生的名称命名您的单例方法时,才需要以下解决方法,即 OP 质疑方法名称是模型,而类称为 MyModel.

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.

如果该方法重命名为类似单例的方法,则可以像这样从 Swift 调用它:

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()

++++++++++++

+++++++++++

我不知道这是否是好的/坏的做法,但我能够通过添加一个虚拟的 init 方法来解决在没有参数时初始化器转换不起作用的问题.因此,以其他答案中的代码为例:

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)

上面的代码没有调用 thing 方法,而是调用 thingWithFoo:bar: 方法.

With this code above the thing method is not called, but the thingWithFoo:bar: method is.

但是如果更改为 this 那么现在将调用 thing 方法:

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)

这篇关于如何从 Swift 调用 Objective-C 单例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆