2015-09-21 20 views
10

Karma bir çerçeve üzerinde çalışma. Obj-C dosyası içine içe aktarılır, ancak iç sınıflar görünür değildir, yalnızca halka açık olanlar.Aynı çerçevede Objective-C'deki dahili Swift sınıfına nasıl erişilir?

belgeler açıkça iç clasees Swift ve Obj-C arasında mevcut olmalıdır devletler

: aynı çerçeve hedefte Swift dosyaları kümesi aktarmak için Objective-C
içine Swift İthalat

senin Objective-C kodu, , çerçeve için şemsiye başlığına herhangi bir şey almanız gerekmiyor. Bunun yerine, Swift kodunuzu kullanmak istediğiniz herhangi bir Objective-C .m dosyasına, Swift kodunuzun için Xcode tarafından oluşturulan başlık dosyasını içe aktarın. Çerçeve hedefi için oluşturulan üstbilgi, çerçevesinin genel arabiriminin bir parçası olduğu için, yalnızca genel değiştiricisiyle işaretlenen bildirimler, bir çerçeve hedefi için oluşturulan üstbilgide görünür. Sen hala Swift yöntemleri ve çerçevenin Objective-C parçası içinden dahili düzenleyici ile işaretlenmiştir özelliklerini kullanabilirsiniz, yeter ki bir Objective-C sınıfından devralan bir sınıf içinde bildirilir . Erişim düzeyi değiştiricileri hakkında daha fazla bilgi için, The Swift Programming Language (Swift 2) numaralı telefondan Access Control'a bakın. dokümanlarında belirtildiği gibi

Kod Numuneinternal değiştirici ile işaretlenmiş beyanlar oluşturulan görünmez,

// SwiftObject.swift 

public class SwiftObject: NSObject { 
    public class func doSomething() {} 
} 

internal class YetAnotherSwiftObject: NSObject { 
    internal class func doSomething() {} 
} 

// SomeObject.m file 

@implementation SomeObject 

- (void)someMethod { 
    [SwiftObject doSomething]; 
} 

- (void)someOtherMethod { 
    [YetAnotherSwiftObject doSomething]; // Use of undeclared identifier 
} 

@end 

cevap

16

(bir çerçeve ile yeni bir proje oluşturun) başlık, böylece derleyici onları ve dolayısıyla şikayetleri bilmez. Tabii ki, performSelector yaklaşımını kullanarak mesaj gönderebilirsiniz, ancak bu uygun ve hataya eğilimli değildir. Derleyicinin bu bildirimlerin orada olduğunu bilmesine yardım etmeliyiz.

// SwiftObject.swift 

@objc(SWIFTYetAnotherSwiftObject) 
internal class YetAnotherSwiftObject: NSObject { 
    internal class func doSomething() {} 
} 

Sonra da kullanmak istediğiniz yöntemlerle @interface beyanı oluşturmak gerekir:

Önce, Objective-C içinde sembol adını belirlemenizi sağlar @objc özellik varyantını kullanmak gerekir kodunuzdaki - yani derleyici mutlu olacak, hem de daha önce belirttiğiniz sembol adıyla makro SWIFT_CLASS uygulamak - bu yüzden bağlayıcı gerçek uygulama alacağını:

// SomeObject.m file 

SWIFT_CLASS("SWIFTYetAnotherSwiftObject") 
@interface YetAnotherSwiftObject : NSObject 

+ (void)doSomething; 

@end 


@implementation SomeObject 

- (void)someOtherMethod { 
    [YetAnotherSwiftObject doSomething]; // Should work now !!! 
} 

@end 
  • Arabirim bildirimini .m dosyasında sadece açıklık için kullandım, daha iyi seçenek bu bildirimleri .h dosyasında birleştirmek ve içermek olabilir.
  • Bu arabirimde yöntemleri bildirerek derleyiciye bir vaat veriyoruz ve var olmayan bir yöntemi (veya yanlış imzalı vb.) Koyacağınız konusunda şikayet etmeyeceksiniz. Açıkçası, Bu durumda çalışma zamanında çökme - bu yüzden dikkatli olun.
+0

Güzel! Bu makroyu bilmiyordum ve google fazla bir şey göstermiyor. Apple dokümanlarından herhangi bir referansınız var mı? – Yariv

+4

Güzel mi? Bu korkunç bir şekilde berbat ve dağınıktır. Yapman gereken bu gerçekten mi? Aynı problemle karşılaştım ve hatta elma bundan daha iyi bir şey yapmayı başarmış olmalıydı. Bundan vazgeçip nesnel c'ye geri döneceğim, bu mantıksız! Gerçekte çalışan bir şey yayınlamak için +1 (arama saatlerinden sonra). –

+3

Apple belgelerine göre "Artık bir Objective-C sınıfından miras alınan bir sınıf içinde bildirildikleri sürece, iç düzenleyici ile işaretlenmiş Swift yöntemlerini ve özelliklerini çerçevenizin Objective-C bölümünden kullanabilirsiniz", eğer hızlı sınıf başka bir obj sınıfından türerse, bu, nesne kodunda mevcut olmalıdır. Benzer bir sorunum var ve hızlı sınıfımı @objc ile işaretledim ve NSObject öğesinden devralmaya devam ediyor, ancak yine de nesne kodunda bulunmuyor. – puru020

3

Benim için sadece "Yalnızca uygulama uzantısı API'sine izin ver" seçeneğini işaretleyerek çalıştı.Proje ayarına gidip hedefinizi seçerek ve ardından Dağıtım Bilgileri altındaki Genel sekmesinde bulabilirsiniz.

Birisi bana, neden bu sorunu çözdüğünü açıklayabilir mi?

+0

Seni seviyorum! LOL. Bu aptal sınırlamayı atlamak için cevabı bulan dünyadaki tek yer burası. Swift sınıflarını sadece iç ObjC koduyla etkileşime girebilmek için API tüketicilerine sunacak bir çerçeve gerekmemelidir! – nobre

+0

Bu seçeneği denemeye dikkat edin! Otomatik oluşturulan başlıktaki sınıf ve yöntemleri listeler. Sadece özel olanı saklamaya özen göstermezseniz kullanın. – Amit

+0

Ancak bu işaretlendiğinde, bir miktar Kakao API'si eksik olacak. – Martin