Zapoznaj się z dokumentacją NSObject
. W tym przypadku:
[parent performSelector:sel withObject:[NSNumber numberWithInt:i]];
(Uwaga ta metoda jest faktycznie wymienione w dokumentacji NSObject
protocol). Od -[NSObject performSelector:withObject:]
wymaga argumentu obiektu, trzeba będzie napisać otoki w klasie rodzica jak
-(void)myMethodForNumber:(NSNumber*)number {
[self myMethod:[number intValue]];
}
do unbox się NSNumber
.
Jeśli naprawdę chcesz wywołać metodę, która pobiera argumentów non-object bezpośrednio (na przykład, nie masz kontroli źródła odbierającego i nie chcą, aby dodać kategorię), można użyć NSInvocation
:
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
Na marginesie, twoja metoda wygląda jak metoda init
, ale nie jest zgodna z prawidłowym wzorcem inicjalizacyjnym dla Objective-C. Musisz wywołać inicjator super-klas i musisz przetestować pod kątem wyniku nil
z tego połączenia i musisz zwrócić ja z metody inicjalizującej. We wszystkich przypadkach, swoje metody initializer Objective-C powinna wyglądać następująco:
-(id)myInitMethod {
self = [super init];
if(self != nil) {
//perform initialization of self
}
return self;
}
metodę (jeśli jest to metoda startowych) będzie wtedy wyglądać tak:
-(id) init: (SEL)sel owner:(NSObject*) parent
{
self = [super init];
if(self != nil) {
int i = 10;
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
}
return self;
}
Aby być bardziej Objective-C stylistycznie, Zmieniłbym również nazwę inicjatora -(id)initWithSelector:owner:
.
dzięki, to wychodzi poza nie. Zgadłem, że mogę potrzebować użyć NSInvocation, ale nie byłem pewien. Świetna odpowiedź. – madmik3
Odkładając na bok, nawet jeśli nie masz kontroli nad uczestnikiem, możesz nadal napisać metodę wrapper, używając kategorii z tej klasy, aby rozpakować obiekt do typu pierwotnego. –
Dobra uwaga, wyd. –