2012-01-06 16 views
6

Bir protokolün direktifinin @selector gibi @protocol olduğunu biliyorum, ancak bir Protokol'e başvurmak için "tip" nedir (örn. SEL için @Selector)? MacOSX yığında, bu Protokol *?Amaç-C'de nasıl başvuru yapılır?

id<TheNameOfTheProtocol> aVariableToThatProtocol; 

Veya bir mesaj (Protocol *) nesneyi isterse:

[myObject conformsToProtocol:@protocol(TheNameOfTheProtocol)]; 

cevap

13

Sen olarak başvuru?

elma resmi DOC sevk ve bir protokolde diğer protokollere başvurmak için bir basit bir örnek bulundu:

#import "B.h" 

@protocol B; // To break the recursive cycle, you must use the @protocol directive to make a forward reference to the needed protocol instead of importing the interface file where the protocol is defined 

@protocol A 
    - foo:(id <B>)anObject; 
@end 

protokol B şöyle bildirildi:

#import "A.h" 

@protocol B 
    - bar:(id <A>)anObject; 
@end 

@protocol yönergesini bu şekilde kullanırken, derleyiciye B'nin daha sonra tanımlanacak bir protokol olduğunu bildirmeniz yeterlidir. Protokol B'nin tanımlandığı arayüz dosyasını içe aktarmaz. İstediğiniz


Ve here're fazla şeyler hakkında bilmek: Birçok yönden

, protokoller sınıf tanımlarına benzer. Her ikisi de yöntemleri bildirirler ve çalışma zamanında her ikisi de Nesneler tarafından temsil edilirler - sınıf örnekleri ve protokoller tarafından Protokol örneklerine göre sınıflar. Sınıf nesneleri gibi, protokol nesneleri de kaynak kodda bulunan tanımlardan ve beyanlardan otomatik olarak oluşturulur ve çalışma zamanı sistemi tarafından kullanılır. Program kaynak kodunda tahsis edilmediler ve başlatılamıyorlar.

kaynak kodu burada sondaki parantez grubu vardır haricinde @protocol() yönergesi bir protokol beyan-aynı yönergesi kullanarak bir protokol nesnesine başvurabilir.

Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport); 

Bu kaynak kodu bir protokol nesnesi hokkabaz tek yoludur: parantez protokol adı içine. Bir sınıf adı aksine, bir protokol adı nesneyi belirtmez — inside @protocol().


Ve dahası, it a conformsToProtocol: mesajı göndererek bir nesne bir protokole uygun olup olmadığını kontrol etmek mümkündür:

if (! [receiver conformsToProtocol:@protocol(MyXMLSupport)] ) { 
    // Object does not conform to MyXMLSupport protocol 
    // If you are expecting receiver to implement methods declared in the 
    // MyXMLSupport protocol, this is probably an error 
} 

conformsToProtocol: testi gibidir tek bir yöntem için TOSelector: testine yanıt verir, ancak bir protokolün kabul edilip edilmediğini test eder (ve muhtemelen tüm Belirli bir yöntemin uygulanıp uygulanmadığını değil, uygulamaya koyduğunu beyan eder. Protokoldeki tüm yöntemleri denetlediğinden, conformsToProtocol:, yanıtlarından daha verimli olabilirToSelector:.

conformsToProtocol: testi isKindOfClass gibi aynı zamanda: testi, bir protokol yerine kalıtım hiyerarşisi dayalı bir türüne göre bir türü için test haricinde.

+0

Sadece merak, bir protokol "tip" bir "kimliğine sahip kullanılmalıdır herhangi bir neden ?" Bir C# arka planından geldiğinizde, bir sınıf referansına benzer bir beyanı (örn. IProtocol protokolü;) kullandığınızdan, bir arayüz referansını görselleştirmek biraz daha kolaydır. – 5StringRyan

+0

@ 5StringRyan Mantığı bilmiyorum, ancak 'id' türü bir NSObject olmasa bile, herhangi bir nesne için genel bir türüdür. Bu sözdiziminin bir avantajı, çoklu protokollere izin vermesidir. Nesnenin her iki protokole uygun olduğunu ifade etmek için "Kimlik " satırları boyunca bir şeyler yapabilirsiniz. Veya, protokolünüz NSObject ile uyumlu değilse, ancak başvuruda bulunduğunuz bir sınıf örneğini aşağıdakileri yapabilirsiniz: id '. –

+3

@ 5StringRyan, bu tür * * * 'id' olması gerekir. örnek: NSArray * var = [NSArray dizisi]; 'yasal olarak bazen yararlıdır. Ayrıca NSArray * var = [NSArray dizisi]; 'sooo'yu da yazabilirsiniz ... bu kesinlikle bir tür güvenlik enjekte etmenin iyi bir yoludur. (Örnekler aptalcadır - sadece sözdizimini gösterirler) – justin

4

id <YourProtocol> delegate (protokolünü başvurmak için kullanılır)

2

O OS X aynıdır:

Protocol * p = objc_getProtocol("UITableViewDataSource"); 

O <objc/runtime.h> beyan ediyor:

typedef struct objc_object Protocol; 
İlgili konular