Ответ 1
Примечание. Все изменилось, поскольку этот ответ был впервые написан - см. обновления в конце!
Да, это делает шов, чтобы быть ошибкой... хотя, контроль Obj-C runtime имена методов работает:
Скажем, мы определяем пару минимальных классов 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
должен быть видимым только для Obj-C как SwiftFoo
, поскольку это то, что обещает сделать @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 минут в видео). Соответствующая документация Предоставление Swift интерфейсов в 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