SEL выполняет выбор и аргументы

Кажется, должен быть простой способ вызвать селектор с некоторыми аргументами, когда все, что у вас есть, является объектом SEL. Я не могу найти правильный синтаксис.

-(MyClass*) init: (SEL)sel owner:(NSObject*) parent { int i =10; [parent performSelector:sel:i ]; } 

Взгляните на документацию NSObject . В этом случае:

 [parent performSelector:sel withObject:[NSNumber numberWithInt:i]]; 

(обратите внимание, что этот метод фактически указан в документации протокола NSObject ). Поскольку -[NSObject performSelector:withObject:] требует аргумент объекта, вам придется написать оболочку в classе родителя, например

 -(void)myMethodForNumber:(NSNumber*)number { [self myMethod:[number intValue]]; } 

чтобы удалить NSNumber .

Если вы действительно хотите вызывать метод, который напрямую принимает не-объектные аргументы (например, вы не имеете контроля над источником вызова и не хотите добавлять категорию), вы можете использовать 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]; 

С другой стороны, ваш метод выглядит как метод init , но не соответствует правильному шаблону инициализации для Objective-C. Вам нужно вызвать инициализатор суперclassов, и вам нужно проверить nil результат этого вызова, и вы должны вернуть себя из метода инициализатора. Во всех случаях ваши инициализаторы Objective-C должны выглядеть так:

 -(id)myInitMethod { self = [super init]; if(self != nil) { //perform initialization of self } return self; } 

Ваш метод (если это метод init) будет выглядеть так:

 -(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; } 

Чтобы быть более Objective-C стилистически, я бы переименовал инициализатор -(id)initWithSelector:owner: также.

что сказал Барри Уорк. Я просто изменил дискуссию для ленивых программистов

 -(void)myMethodWith:(int)number andBOOL:(BOOL) someBool andStr:(NSString *)str{ NSLog(@"%d %d %@",number,someBool,str); } -(void) testMethod{ SEL sel = @selector(myMethodWith:andBOOL:andStr:); int i = 10; BOOL bol = YES; NSString *str = @"hey baby !"; NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:sel]]; [inv setSelector:sel]; [inv setTarget:self]; [inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation [inv setArgument:&bol atIndex:3]; [inv setArgument:&str atIndex:4]; [inv invoke]; } 

Вы хотите использовать performSelector:withObject: сложная часть преобразует int в NSObject. Вы не можете использовать performSelector с сообщениями, которые принимают int params, вместо этого он должен принимать id .

Из ссылки на протокол NSObject :

aSelector должен идентифицировать метод, который принимает один аргумент идентификатора типа. Для методов с другими типами аргументов и возвращаемыми значениями используйте NSInvocation .

Как только это изменение будет сделано, вы можете сделать:

 id arg = [NSNumber numberWithInt:10]; [parent performSelector:sel withObject:arg]; 

Для методов, которые принимают один или два объекта id типа в качестве аргументов, вы можете использовать:

 [parent performSelector:sel withObject:argument1]; 

или

 [parent performSelector:sel withObject:argument1 withObject:argument2]; 

Для методов с другими типами аргументов создайте NSInvocation которые могут инкапсулировать вызовы произвольных методов.

Вы можете использовать:

 - (id)performSelector:(SEL)aSelector withObject:(id)anObject - (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject 

Или, если вам нужно использовать более сложный метод, используйте class NSInvocation

Давайте будем гением компьютера.