xcode - 暴露给 Objective-C 代码时 Swift 类的名称不遵循 @objc 重命名

标签 xcode swift

给定一个 Swift 类的声明

@objc(NSFoo) public class Foo {
   public func bar() -> () {}
}

根据我对文档的阅读,我希望在 Objective-C 方面我们能够使用标识符 NSFoo 来引用此类。这似乎不是我正在发生的事情。 ProjectName-Swift.h 中生成的定义是:

SWIFT_CLASS("NSFoo")
@interface Foo
- (void)bar;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

而我所期望的是

SWIFT_CLASS("Foo")
@interface NSFoo
...

我正在使用 Xcode 6.0.1。

我遗漏了什么,或者这只是一个 Xcode 错误?

最佳答案

注意:自从首次撰写此答案以来,情况发生了变化 - 请参阅末尾的更新!

是的,这确实是一个错误...不过,控制方法的 Obj-C 运行时名称确实有效:

假设我们定义了一对相互交互的最小 Obj-C 和 Swift 类:

Foo.swift

import Foundation

@objc(SwiftFoo)
class Foo { // inheriting from NSObject makes no difference in this case

    @objc(postcardFromSwift)
    class func postcard() -> String {
        return "Postcard from Swift!"
    }

    @objc(getMailInSwift)
    class func getMail() {
        if let hello = NSBar.postcard() { // NSBar is an Obj-C class (see below)
            println("Printed in Swift: \(hello)")
        }
    }
}

NSBar.h

#import <Foundation/Foundation.h>

@interface NSBar : NSObject
+ (NSString *)postcard;
+ (void)getMail;
@end

NSBar.m

#import "NSBar.h"
#import "ObjS-Swift.h"

@implementation NSBar
+ (void)getMail {
    // notice that I am not referring to SwiftFoo in spite of @objc(SwiftFoo)
    printf("Printed in Objective C: %s", [[Foo postcardFromSwift] UTF8String]);
}
+ (NSString *)postcard {
    return @"Postcard from Objective C!";
}
@end

如果我们现在从 main.m 调用它们的类方法:

#import <Cocoa/Cocoa.h>
#import "NSBar.h"
#import "ObjS-Swift.h"

int main(int argc, const char * argv[]) {

    // notice that I am not referring to SwiftFoo in spite of @objc(SwiftFoo)
    [Foo getMailInSwift]; 
    [NSBar getMail];

    return NSApplicationMain(argc, argv);
}

这将打印以下内容:

// --> Printed in Swift: Postcard from Objective C!
// --> Printed in Objective C: Postcard from Swift!

但它不应该有! Foo 应该只作为 SwiftFoo 对 Obj-C 可见,因为这是 @objc(SwiftFoo) promise 要做的。实际上,使用 SwiftFoo 会触发 Use of undeclared identifier 编译器错误。这确实适用于方法名称的事实,毫无疑问这是一个错误。我很惊讶你似乎是第一个问这件事的人!再加一个!

是的:

// <#ModuleName#>-Swift.h
SWIFT_CLASS("SwiftFoo")
@interface Foo
+ (NSString *)postcardFromSwift;
+ (void)getMailInSwift;

... 类名的接缝是否反转,但这就是该宏的工作方式 – 参见 WWDC 视频 Swift Interoperability In Depth (c. 45 分钟和 c. 48 分钟进入视频)。相关文档为Exposing Swift Interfaces in Objective-C .

Xcode 7 测试版 4

问题现已解决(感谢@ScottBerrevoets 的评论)。

Xcode 7.1

(感谢@Pang 的评论)

@objc class C { } // error: only classes that inherit from NSObject can be declared @objc

关于xcode - 暴露给 Objective-C 代码时 Swift 类的名称不遵循 @objc 重命名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26132823/

相关文章:

swift - 通过触摸在场景中四处移动

sql - 如何使用watchkit实现watch-only数据库

swift - 如何停止所有 SWIFTUI 按钮一起切换?

html - 如何将HTML中的具体内容解析到我的App中

ios - UIDatePicker 最小和最大日期不变

iphone - Obj-C @synthesize

objective-c - ld : library not found for -lIOKit. clang xcode

swift - 警告 : Expression following 'return' is treated as an argument of the 'return'

Xcode 8 和 9 : how to disable code completion when clicking "Tab"

swift - "Use of undeclared identifier ' __BYTE_ORDER ' "更新 Pod 后出错