Swift 4 modunda Swift 3 @objc çıkarım kullanımı kullanımdan kaldırıldı mı?


485

Kısacası, Xcode 9 Beta kullanırken aşağıdaki uyarıyla karşılaştım:

Swift 4 modunda Swift 3 @objc çıkarımının kullanımı kaldırıldı. Lütfen kullanımdan kaldırılmış @objc çıkarsama uyarılarını ele alın, kodunuzu "Kullanımdan kaldırılmış Swift 3 @objc çıkarımı kullanımı" günlüğü etkinken test edin ve Swift 3 @objc çıkarımını devre dışı bırakın. **

Biraz araştırma yaptıktan sonra, sorunu nasıl çözeceğimi bilmiyorum. Bu sorunun nasıl çözülebileceğine ve neler olup bittiğine dair bir açıklama için çok teşekkür ederim.

Amacım kodumda neler olup bittiğini daha iyi anlamak.


4
Hangi nesneye neden olduğunu uyarı iletisinden gerçekten alamıyorum. Xcode bu nesnenin hangi satırda olduğunu söylemez. Bu uyarının nereden geldiğini nasıl öğrenebilirim?
olyv

Yanıtlar:


816

Hedeflerimin "Swift 3 @objc Inference" oluşturma ayarını "Varsayılan" olarak değiştirerek bu uyarıdan kurtuldum.

Xcode9'da Swift 3 @objc çıkarımını devre dışı bırak

Gönderen bu makalede :

Swift 4'ten önce, derleyici bazı Swift bildirimlerini otomatik olarak Objective-C için kullanılabilir hale getirdi . Örneğin, biri NSObject sınıfından alt sınıflandıysa, derleyici bu sınıflardaki tüm yöntemler için Objective-C giriş noktaları oluşturdu. Mekanizmaya @objc çıkarsama denir.

Swift 4'te, tüm bu Objective-C giriş noktalarını oluşturmak maliyetli olduğundan , bu tür otomatik @ objc çıkarımları kullanımdan kaldırılmıştır . "Swift 3 @objc Inference" ayarı "Açık" olarak ayarlandığında, eski kodun çalışmasına izin verir. Ancak, ele alınması gereken kullanımdan kaldırma uyarılarını gösterecektir. Bu uyarıların "düzeltilmesi" ve ayarın yeni Swift projeleri için varsayılan "Varsayılan" olarak değiştirilmesi önerilir .

Daha fazla bilgi için lütfen bu Swift teklifine bakın .


5
Teşekkürler Evgenii. Bu uzun vadeli bir çözüm mü?
DaleK

6
@DaleK evet, inanıyorum. Cevabımda bahsettiğim Swift teklifine göre, objc çıkarımından vazgeçildi. "Swift 3 objc Inference" ayarı yalnızca Swift'in eski sürümlerinden taşınan projelerde bulunur. Biri yeni bir proje yaratırsa, ayar artık mevcut değildir, bu da objc çıkarımının kapalı olduğu anlamına gelir. Herhangi bir objc çıkarsama uyarısının ele alınması ve "Kapalı" olarak ayarlanması tavsiye edilir.
Evgenii

4
XCode'daki bilgi mesajı şunu gösterir: " @objcSwift 4 modunda Swift 3 çıkarımının kullanımı kullanımdan kaldırıldı. Lütfen kullanımdan kaldırılan @objcçıkarım uyarılarını ele alın, kodunuzu" Kullanımdan kaldırılmış Swift 3 @objcçıkarımının kullanımı "günlüğü etkinken test edin ve Swift 3 @objcçıkarımını devre dışı bırakın ." Adı geçen Swift 3 @objcçıkarım kaydını nerede etkinleştireceğiniz hakkında bir fikriniz var mı?
courteouselk

4
@courteouselk, Swift teklifine göre, günlüklerdeki Objective-C giriş noktalarının kullanımını görmek için SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT çevresel değişkeni 1'den 3'e kadar değerlere ayarlanabilir.
Evgenii

14
Sadece eklemek için - Bunu sadece proje için değil, tüm yapı etiketleri için yapmanız gerekir.
Krivvenz

270

- @objcÇıkarım nedir? Ne oluyor?

İçinde Swift 3, derleyici @objcbir dizi yere girer , böylece zorunda kalmazsınız. Başka bir deyişle, @objcsizin için eklemeyi sağlar!

İçinde Swift 4, derleyici artık bunu yapmıyor (o kadar). Şimdi @objcaçıkça eklemelisiniz .

Varsayılan olarak, Swift 4 öncesi bir projeniz varsa, bu konuda uyarılar alırsınız. Bir Swift 4 projesinde, derleme hataları alacaksınız. Bu, SWIFT_SWIFT3_OBJC_INFERENCEyapı ayarı ile kontrol edilir . Swift 4 öncesi bir projede bu olarak ayarlanır On. Bunu şimdi Defaultveya Offyeni bir projede varsayılan seçenek olan (veya ) olarak ayarlamanızı öneririm .

Her şeyi dönüştürmek biraz zaman alacaktır, ancak Swift 4 için varsayılan olduğundan, yapmaya değer.

- Derleyici uyarılarını / hatalarını nasıl durdurabilirim?

Kodunuzu dönüştürmenin iki yolu vardır, böylece derleyici şikayette bulunmaz.

Bunlardan biri, @objcObjective-C çalışma zamanına maruz bırakılması gereken her işlev veya değişken üzerinde kullanmaktır :

@objc func foo() {

}

Diğeri @objcMembersbir Classdeklarasyon ile kullanmaktır . Bu , sınıftaki TÜM işlevleri ve değişkenleri otomatik olarak eklemenizi @objcsağlar . Bu kolay bir yoldur, ancak bir maliyeti vardır, örneğin, maruz kalması gerekmeyen işlevleri ortaya çıkararak uygulamanızın boyutunu artırabilir.

@objcMembers class Test {

}

- Nedir @objcve neden gereklidir?

Bir Swift sınıfına yeni yöntemler veya değişkenler eklerseniz, bunları işaretleme olarak @objcObjective-C çalışma zamanına maruz bırakır. Swift sınıfınızı kullanan Objective-C kodunuz varsa veya gibi Objective-C tipi özellikler kullanıyorsanız bu gereklidir Selectors. Örneğin, hedef eylem modeli: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- Neden her şeyi işaretlemeyeyim ki @objc?

Bir şeyi işaretlemekle birlikte gelen negatifler vardır @objc:

  • Artan uygulama ikili boyutu
  • İşlev aşırı yüklenmesi yok

Lütfen bunun çok üst düzey bir özet olduğunu ve yazdığımdan daha karmaşık olduğunu unutmayın. Daha fazla bilgi için asıl teklifi okumanızı tavsiye ederim.

Kaynaklar:


@objcDinamik dağıtım anlamına gelmez, Swift statik veya sanal dağıtım kullanmakta serbesttir (ve sonuç olarak muhtemelen farklı kodlar yürütebilir). dynamicAnahtar kelime dinamik sevk kullanmaya Swift zorlamak için gereklidir.
kevin

7
Düğmeye eylem eklemenin başka yolları var mı? Eğer @objcsınırlandırılmışsa ne kullanmalıyız?
Aznix

5
@ Stefanif evet, dönüştürmek için biraz olabilir. Aşamalara ayırın. Leave SWIFT_SWIFT3_OBJC_INFERENCEat On. Swift 4 dönüştürün. Sonra @objcşeyler mücadele . Basitleştirmek için temel kurallara uyun: Swift sınıfı Objc-C kodunda (köprüleme başlığı üzerinden) kullanılıyorsa @objcMembers, aksi halde tek tek ekleme özelliğini kullanın @objc. Swift sınıfının herhangi bir .mdosyadan çağrılıp çağrılmadığını öğrenmek için Xcode aramasını kullanın . Bu, dönüşümü nispeten ağrısız hale getirmelidir.
kgaidis

5
@DaleK bu cevap kabul edilmelidir. Uyarıları bastırmak ve Swift 3'teki gibi çalışmasını sağlamak bir seçenektir, ancak IMHO en iyisi değildir. @objcSwift 4'te neden değiştiğini anlamak ve ardından projeyi düzeltme ve aynı tutma kararını vermek önemlidir.
derpoliuk

2
Bu kısa açıklama için teşekkürler
Schmoudi

48

Yükseltici ihtiyaç olduğunu tüm fonksiyonları tespit edemez @objc Muhtemel Objective-C olarak işaretlenmiş Thunks kaldırılmış yardıma bunları bulmak
kaldırılan yöntemlerinin hakkında uyarılar oluşturun •
Thunks kaldırılmış calistiriken • Konsol mesajlar

resim açıklamasını buraya girin


1
Peki @objc ile ne yapmalıyım? onu kaldır? bırak? Bunu zaten kaldırdım. ve bu uyarıyı aldım, bu yüzden onları eklemeliyim? 3. adımda bununla ne yapmalıyım?
Shial

@Objc'i fondan hemen önce ekle
Hassan Taleb

1
3. adımın tamamı ne hakkında? Bazı açıklamalar ekleyebilirsiniz :)
Shial

Ve benim durumumda, bu uyarıyı alıyorum, ancak hiçbir kod işaret edilmiyor. @Objc olarak işaretlenmiş iki yöntem vardır ve buna ihtiyaç duyanlar gibi görünürler. Varsayılan olarak değiştirdim ve derleme sırasında uyarıları almaya devam ediyorum.
Maury Markowitz

12

"Swift 3 @objc Inference" = "Varsayılan" ayarıyla bu uyarıyı aldım. Sonra bunun proje için belirlendiğini fark ettim - hedef için değil. Bu nedenle, uyarıdan kurtulmak için hedefinizde "Varsayılan" ayarınızın olduğundan emin olun.


Proje ayarlarında Varsayılan olarak değiştirdikten sonra bile hatayı çözmek isteyen 20 dakika harcadım. Hedefte de değiştirilmesi gerektiğini tam olarak belirttiniz.
SkrewEverything

8

"AÇIK" yerine "varsayılan" a geçmeniz yeterlidir. Apple mantığına daha bağlı görünüyor.

(ancak @objkalıntıların kullanımına ilişkin diğer tüm yorumlar geçerliliğini korur.)


7

Gerçekten de, Swift 3 @objc Inference özelliğini devre dışı bırakarak bu uyarılardan kurtulacaksınız. Ancak, ince sorunlar ortaya çıkabilir. Örneğin, KVO çalışmayı durduracaktır. Bu kod Swift 3 altında mükemmel çalıştı:

for (key, value) in jsonDict {
    if self.value(forKey: key) != nil {
        self.setValue(value, forKey: key)
    }
}

Swift 4'e geçtikten ve "Swift 3 @objc Inference" öğesini varsayılan olarak ayarladıktan sonra, projemin bazı özellikleri çalışmayı durdurdu . Bunun için bir çözüm bulmak biraz hata ayıklama ve araştırma gerektirdi. En iyi bilgime göre, seçenekler şunlardır:

  • "Swift 3 @objc Çıkarımını" etkinleştir (yalnızca mevcut bir projeyi Swift 3'ten geçirdiyseniz çalışır) resim açıklamasını buraya girin
  • Etkilenen yöntemleri ve özellikleri @objc olarak işaretleyin resim açıklamasını buraya girin
  • @ObjcMembers kullanarak tüm sınıf için ObjC çıkarımını yeniden etkinleştirin resim açıklamasını buraya girin

@Objc çıkarımını yeniden etkinleştirmek sizi uyarılarla sonuçlandırır, ancak bu en hızlı çözümdür. Yalnızca önceki bir Swift sürümünden taşınan projeler için kullanılabilir olduğunu unutmayın. Diğer iki seçenek daha sıkıcıdır ve bazı kod kazma ve kapsamlı testler gerektirir.

Ayrıca bkz. Https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md


7

Ben zaman zaman iOS geliştiriciyim (yakında daha fazla olacak) ama yine de ayarı diğer cevabın yönlendirdiği gibi bulamadım (cevabın gösterdiği Anahtarlık ürününe sahip olmadığımdan), şimdi düşündüğümü buldum Bu anlık görüntüyü tıklamanız ve bulmanız gereken vurgulanmış konumlarla ekleyebilirim.

  1. Sol üst kısımdan başla
  2. Proje klasörü simgesini seçin
  3. Proje klasörü simgesinin altındaki ana proje adınızı seçin.
  4. Sağ taraftaki Oluşturma Ayarları'nı seçin.
  5. Projenizi HEDEFLER altında seçin.
  6. Çok aşağı kaydırın (veya arama metin kutusunda sözcük çıkarımını arayın)

Ayarı bulma


6

"Kapsül güncelleme" ve / veya "çarpıntı temizliği" yapmayı deneyebilirsiniz

Bu ayarı xcode'da da ayarladım.

Objective-C arayüz ayarı aşağıdaki gibidir:

ObjectiveC arayüz ayarı


2

Swift 3 @objc Çıkarım Swift 4 modunda Swift 3 @objc çıkarım kullanımdan kaldırılmıştır. Lütfen kullanımdan kaldırılmış @objc çıkarsama uyarılarını ele alın, kodunuzu "Kullanımdan kaldırılmış Swift 3 @objc çıkarımı kullanımı" günlüğü etkinken test edin ve ardından "XMLParsingURL" için "Swift 3 @objc Çıkarım" oluşturma ayarını "Varsayılan" olarak değiştirerek çıkarımı devre dışı bırakın hedef.

var

  1. İlk adım Yapı Ayarını aldı

  2. Ayar Çıkarımını Oluşturmak için Arama Yapın

  3. swift'i değiştir 3 @objc Çıkarım Varsayılan

resim açıklamasını buraya girin


1

Yapmanız gereken tek şey bitene kadar bir test bekleyin, ardından Yapı Ayarı'na gidin, Yapı Ayarı Çıkarımında Arayın, swift 3 @objc Çıkarımını (Varsayılan) olarak değiştirin. Yaptığım ve mükemmel çalıştığım şey bu.


0

Swift 4 modunda Swift 3 @objc çıkarım kullanımı kullanımdan kaldırıldı mı?

func call @objc kullanın

func call(){

foo()

}

@objc func foo() {

}

0

@Wisekiddo'nun söylediklerinin yanı sıra , özellikle başka bir ortamdan geliyorsanız project.pbxproj, Swift 3 @obj Çıkarımını SWIFT_SWIFT3_OBJC_INFERENCE = Default;yapı aromalarınızda olduğu gibi varsayılan olarak ayarlayarak dosyadaki oluşturma ayarlarınızı da değiştirebilirsiniz. Xcode'un yanı sıra

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.