2012-12-26 21 views
6

Protokolüm tanımlandı. Protokol yöntemlerinden ikisinden isteğe bağlı olarak bahsettim. Çalışma zamanı sırasında, belirli yöntemin isteğe bağlı olup olmadığını nasıl öğrenebilirim? Bunu öğrenmenin bir yolu var mı?Çalışma zamanı sırasında protokol yöntemi nasıl tanımlanır?

+2

Neden bu bilgiler zamanında ihtiyaç olacağını? (Sadece merak ediyorum.) –

+1

@NikolaiRuhe Yep, bu yoruma +1. Genel olarak, varsayımlar yapmamalı, test özelliklerini yapmamalıyız. I. e., 'Gereken bir yöntemin uygulandığını varsaymak yerine' cevaplarıAçımlayıcı: 'için test etmelidir. –

+0

Veya bir anahtar kelime olarak tüm yöntemlerin adını kendiniz yapabilirsiniz ve bunu kontrol etmek için YES/NO olarak değeri yapabilirsiniz. –

cevap

12

istediğini yapmak Özellikle de neden bunu yapmak istediğinizi açıklamadığınız için nakliye kodunda. Ayrıca, protokolün içermediği bir yöntem için bir seçici verildiğinde bu işlevin NO değerini döndüreceğini unutmayın. Bu temel olarak mantıklıdır (eğer bir protokol bir yöntem içermiyorsa, bu gerekli değildir!), Ancak protokolün yöntemi isteğe bağlı bir yöntem olarak içerip içermediğini kontrol etmek ve farklı bir şey döndürüp döndürmediğini kontrol ederek işlevsellik için karmaşıklık ekleyebilirsiniz. Her üç senaryo (gerekli, isteğe bağlı, protokolde değil).

DÜZENLEME: Burada Basit test programı: https://gist.github.com/4381753

+0

Gerçekten bunu aşırı karmaşık yaklaşımım yerine yapmalıyım. +1. (Bu cevabı bana dahil edebilir miyim?) –

+0

Tabii ki, ve zaten bunu yaptığınızı görüyorum :). –

+0

yep ve ben ekledim :) emin ekledi :) Bu kez benim RTFM olmalıdır ... -.- –

3

(kafamın üst kapalı cevabını bilmiyorum. Googling 1 dakika bana yardım etti.)

Sen Objective-C çalışma zamanı parçası olan protocol_copyMethodDescriptionList() işlevini kullanarak bunu yapabilirsiniz kütüphane (libobjc). Bu işlevin 2. argümanı, protokolde kopyalanacak yöntemlerin gerekip gerekmediğini gösteren bir Boole bayrağıdır. Bu nedenle, bu işlev tarafından döndürülen bir yöntem (uygun argümanlar kullanılarak çağrılır) varsa, bu gerekli bir yöntemdir.

SEL sctr = @selector(isThisMethod:requiredIn:theProtocol:); 

struct objc_method_description *methods; 
unsigned int nMethods; 
methods = protocol_copyMethodDescriptionList(
    objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName) if you don't need this kind of dynamism 
    YES, // required? 
    YES, // instance method? (in general, protocols declare instance methods) 
    &nMethods 
); 

BOOL isRequired = NO; 
int i; 
SEL s; 
const char *sctrStr = sel_getName(sctr); 
for (i = 0; i < nMethods; i++) { 
    s = methods[i].name; 
    const char *sStr = sel_getName(s); 
    if (strcmp(sctrScr, sStr) == 0) { 
     isRequired = YES; 
     break; 
    } 
} 

free(methods); 

if (isRequired) { 
    // required 
} else { 
    // optional 
} 

Yani, bu mümkündür, ancak bir overkill biraz, ve ben zaten soru üzerine benim yorum söylediği gibi, başka bir test etmelidir, bir yöntem isteğe bağlı veya gerekli olan test etmemelidir belirli bir seçiciye cevap vermek.

Düzeltme: evet, tüm evreni kopyalamak yerine, belgelerde daha fazla okumanız gerekir. Andrew Madsen belirttiği gibi, bu birkaç satır indirgenebilir: Bunu kullanarak advisability yorumlarken değilim

BOOL MethodInProtocolIsRequired(Protocol *protocol, SEL methodSelector) 
{ 
    struct objc_method_description methodDesc = protocol_getMethodDescription(protocol, methodSelector, YES, YES); 
    return methodDesc.name != NULL; 
} 

Not: Bu gerektiğini

struct objc_method_description method; 
method = protocol_getMethodDescription(
    objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName) 
    @selector(isThisSelector:required:) 
    YES, // required? 
    YES // instance method? 
); 

if (method.name != NULL) { 
    // required 
} else { 
    // optional 
} 
+1

Yeryüzünde neden bir başkası onu reddediyor? –

+1

Sadece GNU c booleanlarını kullanıyor olsaydınız, sonunda ObjC olmadan objektif-c sorularını cevapladığını söyleyebilirdin! (Son derece teknik olarak olsa da). – CodaFi

+1

@CodaFi: Veya C99 'bool' /' _Bool'. –

İlgili konular