如何在 Swift class 中从 Objective C 调用单例 class 方法?

How do you call a singleton class method from Objective C in a Swift class?

我有以下 objective C 代码,我需要将其输入 Swift class :

在Logger.m -

+ (Logger *) log
{
static Logger *sharedLog = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
    sharedLogger = [[self alloc] init];
});

return sharedLogger;
}

- (void) printString:(NSString *) s
{
    NSLog(s)
}

在 Logger.h 中为 -

+ (Logger *) log;
- (void) printString:(NSString *) s;

现在,我将此代码桥接至 Swift 项目 - LoggerUserApp,我在其中尝试使用来自单例 log 共享 class 方法的上述打印方法。

我试过了 -

Logger.log().printString("String")  // Compiler Error. Use Object Construction Logger()
Logger().log().printString("String")  // Compiler Error. 
Logger().log.printString("String") // Compiler Error. 
Logger.printString("String") // This does not call log

谁能告诉我可能出了什么问题?

我无法完全重现您的示例,但乍一看,这应该可行:

Logger.log().printString("String")

由于您的 Obj-C 单例是一个 函数 returning 单例(因此 Logger.log() 将 return 您的单例。

但是因为在你的示例代码中我看到 Logger 然后 PALog 我不能说这是否就是你所需要的。

您的示例中还有一些其他错误:sharedLogsharedLogger。 这是一个应该有效的示例:

Logger.h

@interface Logger : NSObject

+ (Logger *) log;
- (void) printString:(NSString *) s;

@end

Logger.m

#import "Logger.h"

@implementation Logger

+ (Logger *) log
{
    static Logger *sharedLog = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        sharedLog = [[self alloc] init];
    });

    return sharedLog;
}

- (void) printString:(NSString *) s
{
    NSLog(@"%@", s);
}

@end

...-桥接-Header.h

#import "Logger.h"

ViewController.swift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        Logger.log().printString("Hello")
    }
}

在 Swift 更新中,如果 class 方法的名称与 class 名称相似,那么它只是将其作为自定义初始化程序。现在由于方法中没有参数,它不会出现,因为默认初始化程序会出现。

因此,为了解决这个问题,我不得不将 class 方法的名称 log 更改为不同的名称,例如 newLog... 并且工作正常。

Logger.newLog().printString("")

如果Swift编译器错误地将方法识别为class工厂方法,您可以使用NS_SWIFT_NAME宏,将方法的Swift签名传递给正确导入。例如:

+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));

所以,你的方法应该是这样的:

+ (Logger *) log NS_SWIFT_NAME(log());