ismi,

2014-10-01 15 views
12

belgelerin benim okuma,ismi,

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

ben beklenebilir gibi Swift sınıfın bir deklarasyon Verilen yeniden adlandırma @objc saygı duymayan Objective-C kodu o maruz kaldığında Nesnelerin C-c tarafı, NSFoo tanımlayıcısını kullanarak bu sınıfa başvurabilirdik. Bu benim için olan bir şey değil. ProjectName-Swift.h üretilen tanımı şöyledir: Xcode 6.0.1 kullanıyorum

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

ne beklenebilir olduğunu

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

oysa.

Bir şey eksik mi, yoksa bu bir Xcode hatası mı?

+0

aslında denenmiş mı ve:

[XYZLogger debug:@"Hi from objective C"]; 

böyle Swift Kullanılan Nesne C'de 'NSFoo' olarak başlatılamadı? – milos

+1

@milos Evet. Derleyici 'Tanımlanamayan tanımlayıcı kullanımı 'NSFoo'' – Manav

+0

Sadece bir not ile balks. NS, CA, UI, vb. Gibi zaten kullanılan sınıf öneklerinden herhangi birini kullanmaktan kaçınıyorum ... – Fogmeister

cevap

13

Not: Bu yanıt ilk yazıldığından beri işler değişti - en sondaki güncellemeleri görün!

Evet, bu dikiş yöntemlerinin Obj-C çalışma zamanı adları kontrol olsa ... bir hata olduğunu yapar yaptığı işlerde:

biz etkileşim minimal Obj-C ve Swift sınıfların bir çift tanımlamak Say birbirlerine:

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 

şimdi main.m kendi sınıf yöntemleri, diyelim ki, çağırırsanız:

#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); 
} 

Bu

aşağıdaki yazdırır:

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

Ama olmamalıydı! Foo sadece SwiftFoo olarak Obj-C'ye görünmelidir, çünkü bu @objc(SwiftFoo)'un ne yapmak için umut vericidir. Aslında, SwiftFoo kullanmak, Use of undeclared identifier derleyici hatasını tetikler. Bunun yöntem isimleri için işe yaradığı gerçeği, bunun bir hata olduğunu pek az şüphe bırakıyor. Sadece bu konuda sormak için ilk kişi gibi görünmekten çok şaşırdım! Ayrıca bunun için bir tane!

Ve evet.:.

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

... dikiş sınıf adı için tersyüz edilmesine, henüz bu o makro işler nasıl yok - WWDC Video Swift Interoperability In Depth (c 45 dk ve c bakın 48 dk içine video). İlgili belgeler Exposing Swift Interfaces in Objective-C'dur.

Xcode 7 beta sorun şimdi sabittir 4

(yorum için @ScottBerrevoets sayesinde).

Xcode 7,1

(teşekkürler yorum için @Pang için) (XCode8 cinsinden) Şu

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

Bu, Xcode 7 beta 4 –

+0

'dan itibaren giderilmiştir. Teşekkürler @ScottBerrevoets. Cevabı güncelledim. – milos

+0

Xcode 7.1'de derleyici şunları söylüyor: * "Yalnızca NSObject öğesinden devralınabilen sınıflar @objc" olarak bildirilebilir *. – Pang

3

bu ele alınmıştır görünüyor. XYZLogger.h ve 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 

tanımlanmıştır

böyle objc Kullanıldı:

Logger.debug("Hi from swift"); 
İlgili konular