@Objc Swift'de ne zaman kullanılır?


89

Swift'de aşağıdaki gibi bazı yöntemler görüyorum:

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)

Merak ediyordum, @objc ne zaman kullanılmalı? Bazı belgeleri okudum, ancak Objective-C'de çağrılabilir olmasını istediğinizde @objc bayrağı eklemelisiniz diyorlar.

Ancak, bu Swift'de özel bir işlevdir, @obj ne yapar?


1
güzel soru !!!
Erhan Demirci

Yanıtlar:


68

özel, yalnızca Swift'de görülebileceği anlamına gelir. bu nedenle Objective-C'de görünmek için @objc kullanın. Hızlı bir şekilde özel bir işlevi seçmek için bir işleviniz varsa, bu gereklidir.

@Objc özelliği, Swift API'nizi Objective-C ve Objective-C çalışma zamanında kullanılabilir hale getirir.

Bkz .: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html


1
Öyleyse @objc private func doubleTapGestureRecognized, hem @objc hem de özel olmanın ne anlamı var? Objective-C sınıflarının doubleTapGestureRecognized üzerine yazabileceğini mi söylüyorsunuz?
Wingzero

1
Sanırım, çünkü obj-c'de herhangi bir yöntemin üzerine yazabilirsiniz.
strangetimes

2
Bu cevabın nasıl doğru olduğundan ve Q'sunu nasıl yanıtladığından emin değilim. Burada verilen yanıtlar zaten Q'sunun kendisinde "ancak Objective-C'de çağrılabilir olmasını istediğinizde \ @objc bayrağını eklemeniz gerektiğini söylüyorlar" S: "Bu, swift'te özel bir işlev, \ @obj ne yapıyor?"
KBJ

3
Bağlantılar kopuyor. Özellikle Apple belgelerine. Lütfen buradaki belgelerden temel unsurları çıkarmayı düşünün.
levigroker

57

Başka bir geç cevap, ancak bu sorudaki mevcut cevaplardan hiçbiri OP'nin sorusuna gerçekten cevap vermiyor: Neden Objective-C ve söz konusu üye ile etkileşim için varsa , @objcbir privatesınıf üyesi üzerinde kullanmak zorunda kalacaksınız. @objcözeldir, yani projenizde Objective-C kodunuz olsa bile üyeyi yine de görememeli?

Bunun nedeni, çerçevelerin çoğu Objective-C'de yazıldığından, bazen belirli API'lerle etkileşim kurmak için Objective-C özelliklerine ihtiyaç duyulmasıdır.

Örneğin, şu yolla bir bildirim için kaydolmak istediğimi varsayalım DistributedNotificationCenter:

DistributedNotificationCenter.default.addObserver(self,
                                                  selector: #selector(somethingHappened(_:)),
                                                  name: someNotification,
                                                  object: nil)

Bunun işe yaraması için, somethingHappenedyöntem için seçiciyi alabilmemiz gerekir . Bununla birlikte, seçiciler bir Objective-C konseptidir, bu nedenle yöntem, Objective-C tarafından görünür değilse, bir seçicisi yoktur. Bu nedenle, yöntem özeldir ve keyfi dışında koduyla adlandırılan olmamalıdır bile, bir gerekecektir @objcsırayla DistributedNotificationonun seçicinin aracılığıyla diyoruz edebilmek için, Objective-C ile yazılmış kod.

@objcİhtiyaç duyulan diğer bir yaygın durum , özellikle KVC ve KVO'nun Kakao Bağlamalarını uygulamak için kullanıldığı macOS'ta Anahtar Değer Kodlamasını (KVC) desteklemektir. KVC, Cocoa'daki diğer birçok sistemde olduğu gibi, Objective-C'de uygulanmaktadır ve bu, KVC uyumlu özelliklerin Objective-C çalışma zamanına maruz kalmasını gerektirme etkisine sahiptir. Bazen, KVC uyumlu mülklerin özel olması mantıklıdır. Bir örnek, diğer özellikleri etkileyen bir mülkünüzün olmasıdır:

@objc private dynamic var originalProperty: String

@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
    #keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }

Bu durumda, bizim asıl depolanan özellik özel, ama biz bağımlı özellik, do dışında kod maruz, özel mülkiyet güncellendiğinde de bildirimlerini göndermesi gerekir. Özel mülkü olarak işaretleyerek, @objcbunu bir KVC bağımlılığı oluşturarak kolayca yapabiliriz - aksi takdirde, özel mülk willSetve didSetişleyicilerdeki bildirimleri manuel olarak göndermek için kod yazmamız gerekir . Ek olarak, dependentPropertybağımlı olan KVC sistemini bilgilendiren statik özelliğin originalPropertyObjective-C'ye maruz kalması gerekir, böylece KVC sistemi onu bulur ve çağırır, ancak kodumuzun istemcileri ile ilgili değildir.

Ayrıca, bir uygulama ayrıntısı olarak Cocoa Bindings kullanarak görünümünde kontrolleri güncelleyen bir macOS uygulamasındaki bir görünüm denetleyicisi, bu kontrolleri bunlara bağlamak için belirli özel özellikleri KVC uyumlu hale getirebilir.

Gördüğünüz gibi, kodunuzun istemcileri tarafından görünmesi gerekmeksizin çerçevelerle etkileşime geçmek için bir yöntemin veya özelliğin Objective-C'ye maruz bırakılması gereken zamanlar vardır.


Teşekkürler. Bu, soruyu doğrudan ele alan iyi bir cevaptır.
hqt

25

@objc / dinamik

Uyumluluk içindir: Swift dosyanızı / kodunuzu Objective-C tabanlı projeye aktardığınızda.

Ve mülkünüze / yönteminize Objective-C kodu veya sınıfı tarafından erişilmesini istiyorsanız bunu kullanın.

Çoğu zaman, bir Swift sınıfını Objective-C temel sınıfının alt sınıflarını oluştururken olur.

Bir Swift sınıfı veya protokolünün Objective-C'de erişilebilir ve kullanılabilir olması için @objc niteliği ile işaretlenmesi gerekir . Bu özellik, derleyiciye bu Swift koduna Objective-C'den erişilebileceğini söyler. Swift sınıfınız bir Objective-C sınıfının soyundan geliyorsa, derleyici sizin için otomatik olarak @objc niteliğini ekler.

İşte hakkında yazan elma belgeleri @objc.

Objective-C'den Swift Kullanımı

Dil Birlikte Çalışabilirlik Uyumluluğu

Bağlantılar Güncellendi: Bağlantılar
apple tarafından güncellenmiş gibi görünüyor.


11

@objc bir sınıf özniteliğidir, bu nedenle

@objc public class MyClass

Sınıfın yöntemlerini Objective C sınıflarına sunar, bu nedenle onu yalnızca sınıfınız genel işlevler içeriyorsa kullanırsınız


8

Geç bir cevap, ancak bu @objcdavranış (genellikle 10 gün önce piyasaya sürülen Xcode 9'da çıkan) Swift 4'ten itibaren biraz değişiyor.

Swift 4'te bazı çıkarım durumları @objckaldırıldı. Bu sadece, @objcbaşlığın Swift derleyicisi tarafından çıkarılmadan önce Swift 4'te çıkarsanmadığı bazı ek durumlarda anlamına gelir .

Bu değişiklikle ilgili Swift evrim önerisinde daha fazlasını okuyun

Bahsedildiği gibi, genel @objcolarak, Swift'in dilin birlikte çalışabilirliğinin bir parçası olan Objective-C çalışma zamanına belirli yöntemleri sunmaktır.


1
bu yüzden Swift 4'e güncelledikten sonra bazı değişkenlere ObjC'den erişilememesinin nedeni bu olmalı, değil mi? Swift 3.X ile eklemeye gerek yoktu@objc
rgkobashi

tamam, başka biriyle tekrar kontrol etmek her zaman iyidir, teşekkürler!
rgkobashi

1

@objcbir beyanı ifşa eder Objective-C runtime. #selectorBir Objective-C çalışma zamanı kullanmak için Swift'in özelliğine bir göz atalım . Bu durumda Swift'inizi tanımlayabilirsiniz @objc private func[Daha Fazla]

Swift'in işlevlerini Objective-C'den kullanmak için:

  1. Swift'in sınıfı, NSObject
  2. Mark Swift'in:

    a. yalnızca @objcMembers sınıf - tüm public yapıcıları , alanları ve yöntemleri ortaya çıkarmak için . Ayrıca alt sınıflar için de geçerlidir

    b. @objc sınıf / enum / protokol ( yapı dışında ) [Adlandırılmış Tür]

    • @objc sınıf (isteğe bağlı) - bir varsayılanı göstermek için public init(). Veya @objc(<custom_name>)sınıf için özel bir ad ayarlamak için.
    • @objc kurucular , alanlar ve yöntemler - bunları seçici olarak ortaya çıkarmak için

Swift'in yöntemi bir sonraki adlandırma ile kullanıma sunulacak:

<swiftName>With<firstArgument>:<secondArgument>:

Örneğin:

public func printHelloWorld(arg1: String, arg2:String)
//is reached through: 
[someObject printHelloWorldWithArg1: arg2:];

[ @objcve dynamic]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.