“Ölümcül hata: dizi Objective-C'den köprülenemez” —Neden deniyorsun Swift?


92

Bir Swift protokolü ilan ettim:

protocol Option {
    var name: String { get }
}

Bu protokolün birden çok uygulamasını açıklıyorum - bazı sınıflar, bazı numaralandırmalar.

Şu şekilde bildirilmiş bir özelliğe sahip bir görünüm denetleyicim var:

var options: [Option] = []

Bu özelliği Optionbaşka bir VC'de protokolü uygulayan bir dizi nesneye ayarlamaya çalıştığımda prepareForSegue, bir çalışma zamanı hatası alıyorum:

fatal error: array cannot be bridged from Objective-C

Bu neden çalışmıyor? Derleyici ihtiyaç duyduğu tüm bilgilere sahiptir ve Objective-C'nin bununla ne ilgisi olduğunu anlamıyorum - projem yalnızca Swift dosyalarını içeriyor ve bu diziler herhangi bir çerçeve yöntemine girip çıkmıyor. köprülenmelerini gerekli kılıyor NSArray.


6
@objcProtokolünüze eklemeye çalıştınız mı? stackoverflow.com/a/28029568/377369
Fabio Poloni

1
Protokol uygulamalarından herhangi biri bir numaralandırma ise bu işe yaramaz: "Sınıf dışı tip 'Foo', 'Seçenek' sınıf protokolüne
Robert Atkins

Yine de neden bir sınıf protokolü olmalı? Bunu bir Obj-C çerçevesine veya Swift Array'in NSArray'e köprülenmesini gerektiren başka bir şeye aktarmıyorum.
Robert Atkins

Swift ve Objective-C'nin birlikte çalışma şekli benim için hala bir sır. Sadece "işe yarayan" veya "çalışmayan" birçok şeyi "kabul etmeliyim".
Fabio Poloni

9
Bunun neden bu kadar çok olumsuz oyu var? Bana adil ve net bir soru gibi görünüyor.
Guven

Yanıtlar:


83

Bir çözüm buldum. Oldukça ... tatmin edici değil , ama işe yarıyor. Diziyi hedef görünüm denetleyicisinde ayarladığım yer:

destinationViewController.options = options.map({$0 as Option})

tüm diziyi yapamaz mısın? options as [Option]
Kostiantyn Koval

Hayır! Denedim (Xcode 6.3.1 (6D1002)), çalışmıyor. Herhangi bir durumda onu yayınlamaya ihtiyacım olmamalı , derleyici Option'ı uygulayan şeyler dizisine geçtiğimi biliyor.
Robert Atkins

2
"Seçenek Dizisi'ni uygulayan şeyler dizisi" Ah, ancak bu, ihtiyacınız olan bir Seçenek Dizisi ile aynı değildir. Cevabımı gör.
matt

1
Bu işe yarıyor ve evet çok tatmin edici değil ... buna gerek yok. Swift, htis ile başa çıkabilmelidir.
Oscar Gomez

Aynı fikirdeyim ... bu şekilde çalışıyor, ancak bu çok tatmin edici olmayan bir kod parçası
Michael

22

derleyici, Option'ı uygulayan bir dizi şeyden geçtiğimi biliyor

Sorunun kaynağını öneren çok açıklayıcı bir söz yazdınız. "Option'ı uygulayan şeyler dizisi" bir Seçenek Dizisi değildir.

Sorun, optionsonu oluşturduğunuz (içinde prepareForSegue) noktadaki geri türüyle ilgilidir . Bu kodu göstermiyorsunuz, ama bahse girerim o noktada onu yayınlayamaz / yazamazsınız. Bu yüzden atama başarısız oluyor. optionsAslında Option'ı benimseyen bir dizi şey olabilir, ancak bu yeterli değildir; bir Seçenek dizisi olarak yazılmalıdır .

Öyleyse, geri dönün prepareForSegue, şu şekilde oluşturun options:

let options : [Option] = // ... whatever ...

Şimdi doğrudan atayabileceksiniz destinationViewController.options.

İşte hızlı bir test vakası (bir oyun alanında; oyun alanlarından nefret ediyorum, ancak kullanımlarına sahip olabilirler):

protocol Option {
    var name : String {get}
}

class ViewController : UIViewController {
    var options : [Option] = []
}

enum Thing : Option {
    var name : String {
        get {
            return "hi"
        }
    }
    case Thing
}

let vc = ViewController()
let options : [Option] = [Thing.Thing]
vc.options = options // no problem

(Bunu gerçek bir uygulamada da gerçek bir uygulamada test ettim prepareForSegueve iyi çalışıyor.)


1
Ben derleyici çünkü bu aşırı kırık olduğunu düşünüyorum gelmez Şey Bir Seçenek olduğunu zamanında biliyoruz. Ve her durumda, aşağıdaki kendi cevabımın yorumunda belirtildiği gibi, burada önerdiğiniz gibi viewController.options = things as [Option]açıkça yazılan bir temp değişkeninin ne döküm ( ) ne de oluşturulması [Option]gerçekten işe yarıyor. Her iki durumda da çalışma zamanı hatası alıyorum.
Robert Atkins

O zaman neden benim için işe yaradığını açıklamalısın. Belirtmediğiniz başka bir şey oluyor. Daha fazla kod ifşa etmezseniz, temel bir şeyi geride bıraktığınızdan şüphelenmem gerekir.
matt

Olabilir. Ancak bunun ilk etapta Objective-C ile ne ilgisi olduğu konusunda hala kafam karıştı (orijinal çalışma zamanı hatasıyla ilgili olarak.) NSArray.
Robert Atkins

2
Şu şekilde bak. Size işe yarayan kodu gösterdim. Sen gelmiş değil bana kodunu gösterilmemiştir gelmez Bana verilen verilerden sorununuzu yeniden olamaz - çalışır. Yeniden üretmeme yardım et.
matt

1
@ CristiBăluță "Bu sorun hala çözülmedi" iddiasında bulunmadan önce bulmanız gereken şey bu
matt

16

Aynı problemi yaşıyordum ve protokolümü işaretleyerek düzelttim @objc, senin durumunda böyle görünecekti

@objc protocol Option {
    var name: String { get }
}

Çözümü bu cevaptan aldım


1
Orijinal soru hakkındaki yorumlarda olduğu gibi, protokolün uygulayıcılarından herhangi biri Swift Enums ise bu işe yaramaz. Benim durumumda onlar.
Robert Atkins

typo obcj objc olmalıdır
Alan Scarpa

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.