给出类似
的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错误?
答案 0 :(得分:17)
注意:自从这个答案首次编写以来,情况发生了变化 - 最后看到更新!
是的,这确实是一个错误...但是,控制方法的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)
承诺做的事情。实际上,使用SwiftFoo
会触发Use of undeclared identifier
编译器错误。事实上,这确实适用于方法名称,这让人怀疑这是一个错误。我很惊讶您似乎是第一个提出这个问题的人!再加上一个!
是的:
// <#ModuleName#>-Swift.h
SWIFT_CLASS("SwiftFoo")
@interface Foo
+ (NSString *)postcardFromSwift;
+ (void)getMailInSwift;
...为类名称设置了倒缝,但这就是该宏的工作方式 - 请参阅WWDC视频Swift Interoperability In Depth(约45分钟和约48分钟进入视频)。相关文档为Exposing Swift Interfaces in Objective-C。
Xcode 7 beta 4
现在问题已解决(感谢@ScottBerrevoets的评论)。
Xcode 7.1
(感谢@Pang的评论)
@objc class C { } // error: only classes that inherit from NSObject can be declared @objc
答案 1 :(得分:3)
目前(在XCode8中)似乎已经解决了这个问题。
在XYZLogger.h和XYZLogger.m中定义
NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(Logger)
@interface XYZLogger : NSObject
+ (void)verbose:(NSString *)logString;
+ (void)debug:(NSString *)logString;
+ (void)info:(NSString *)logString;
+ (void)warn:(NSString *)logString;
+ (void)error:(NSString *)logString;
@end
NS_ASSUME_NONNULL_END
在objc中使用:
[XYZLogger debug:@"Hi from objective C"];
像Swift一样在Swift中使用:
Logger.debug("Hi from swift");