Bir protokolün yalnızca belirli bir sınıf tarafından benimsenmesini nasıl talep edilir


91

Bu protokolü istiyorum:

protocol AddsMoreCommands {
     /* ... */
}

yalnızca sınıftan miras alan sınıflar tarafından benimsenir UIViewController. Bu sayfa bana, bunun yalnızca bir sınıf tarafından (bir yapının aksine) yazarak kabul edildiğini belirtebileceğimi söylüyor.

protocol AddsMoreCommands: class {
}

ancak bunun yalnızca belirli bir sınıf tarafından benimsenmesini nasıl talep edeceğimi göremiyorum. Bu sayfa daha sonra,where uygunluğu kontrol etmek için protokol uzantılarına cümle eklemekten bahsediyor, ancak bunu nasıl uyarlayacağımı da göremiyorum.

extension AddsMoreCommands where /* what */ {
}

Bunu yapmanın bir yolu var mı? Teşekkürler!

Yanıtlar:


115
protocol AddsMoreCommands: class {
    // Code
}

extension AddsMoreCommands where Self: UIViewController {
    // Code
}

4
Neredeyse elde edecektim ... Onun selfyerine şunu yazdım Self:-( Çok teşekkür ederim, bu iyi çalışıyor!
emrys57

Benim için bu, döküm ile birlikte kullandığımda bazı sözdizimsel tuhaflıklara neden oluyor.
Chris Prince

3
Uzantılar depolanmış özellikleri içeremeyeceğinden, protokole bir özellik eklemeniz gerekirse bu işe yaramaz.
şim

1
Mülkleri depolamış olabilir, sadece bunu kullanmanız gerekir: objc_getAssociatedObject (self, & KeyName) olarak? Emlak
Türü

Bu ayrıca bir let / var bildiriminin türü olduğunda, AddsMoreCommandsancak bir yöntemi beklemek için UIViewController
ilettiğiniz

80

Bu, bir uzatma olmadan da gerçekleştirilebilir:

protocol AddsMoreCommands: class where Self: UIViewController {
   // code
}

REDAKTE 2017/11/04 : As Zig işaret, bu Xcode 9.1 üzerinde bir uyarı oluşturmak gibi görünüyor. Şu anda Swift projesinde (SR-6265) uyarıyı kaldırmak için bildirilen bir sorun var, buna göz kulak olacağım ve cevabı buna göre güncelleyeceğim.

DÜZENLENMİŞ 2018/09/29 : classörneği depolayacak değişkenin zayıf olması gerekiyorsa (temsilci gibi) gereklidir. Zayıf bir değişkene ihtiyacınız yoksa, atlayabilir classve aşağıdakileri yazabilirsiniz ve herhangi bir uyarı olmayacaktır:

protocol AddsMoreCommands where Self: UIViewController {
   // code
}

5
İki yıllık bir soruyu tıklayıp bir saat önce yayınlanan mükemmel bir çözüm bulmam ne kadar tesadüf 😲
Oscar Apeland

Xcode 9.1 şimdi bu konuda bana bir uyarı veriyor: Redundant layout constraint 'Self': 'AnyObject'. Düzen kısıtlaması 'Self': 'AnyObject' burada ima edilmiştir. Kodumu kabul edilen cevabın formatına değiştirmek daha iyi görünüyor.
Zig

2
Xcode 9.1 itibariyle, yalnızca sınıf protokolleri artık AnyObjectyerine kullanıyor class. protocol AddsMoreCommands: AnyObject where Self: UIViewController { // code }
dodgio

@dodgio hala aynı uyarıyı alıyorAnyObject
rgkobashi

1
@ DávidPásztor haklısınız, ancak yetkilendirme gibi yapısal bir modelde kullanmak istiyorsanız, mülkü zayıflatabilmek için açıkça 'sınıf' eklemeniz gerekir :)
rgkobashi

48

Önceki cevaptaki bir sorun nedeniyle şu beyanı verdim:

protocol AddsMoreCommands where Self : UIViewController { 
    // protocol stuff here  
}

Xcode 9.1'de uyarı yok


5
Yanılıyorsam düzeltin, ancak yukarıdaki çözümle ilgili sorun (Xcode 9.1 ve üstü sürümlerde bir uyarı oluşturuyor), temsilciyi zayıf olarak ilan edememeniz mi?
Kyle Goslan

Ben Swift 4.1 ile bu çözümü kullandığınızda Ayrıca, ben döküm özelliklerine ihtiyaç AddsMoreCommandsiçin UIViewController... ki ben kaçmak istedim
fl034

9
Tip atamasından kaçınmak için şunu yapabilirsiniz:typealias AddsMoreCommandsViewController = UIViewController & AddsMoreCommands
eklenti

35

Şimdi Swift 5'te bunu şu şekilde başarabilirsiniz:

protocol AddsMoreCommands: UIViewController {
     /* ... */
}

Oldukça kullanışlı.

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.