Making dynamic class method calls in Objective-C with more than two parameters

I have a method that dynamically creates new objects of different classes and wants to be able to perform a selector of these classes as they are created. Using performSelector: withObject: might work, but methods have four arguments. I tried the following code using NSInvocation but got an error as it was an unrecognized selector.

 NSInvocation *call = [NSInvocation invocationWithMethodSignature:[NSClassFromString(className) methodSignatureForSelector:@selector(packWithName:value:writer:forClass:)]]; [call setArgument:&arg1 atIndex:0]; [call setArgument:&arg2 atIndex:1]; [call setArgument:&arg3 atIndex:2]; [call setArgument:&arg4 atIndex:3]; call.target = NSClassFromString(className); [call invoke]; 

It also produces the following log statement:

 *** NSForwarding: warning: selector (0x8ed78d0) for message '[garbled random characters]' does not match selector known to Objective C runtime (0x8b0cd30)-- abort 

I also tried creating NSInvocation using alloc / init and installing @selector as follows:

 NSInvocation *call = [[NSInvocation alloc] init]; call.selector = @selector(nameofselector); 

This leads to the fact that call is nil, so I assume this is not valid.

Am I missing something regarding how NSInvocation works or is there a smarter way to do this?

+4
source share
2 answers

The arguments at index 0 and 1 are not the first two explicit arguments to the method call, but the implicit arguments self and _cmd . Use indexes 2, 3, 4, and 5 instead.

+5
source

The Apple documentation just says that the first argument (with index 0) represents the target (so that "I"). Since the documentation explains that the first argument is set using the setTarget: method.

So, you need to start indexes from 2 sides to use NSInvocation. (this means your code should be similar)

 NSInvocation *call = [NSInvocation invocationWithMethodSignature:[NSClassFromString(className) methodSignatureForSelector:@selector(packWithName:value:writer:forClass:)]]; [call setArgument:&arg1 atIndex:2]; [call setArgument:&arg2 atIndex:3]; [call setArgument:&arg3 atIndex:4]; [call setArgument:&arg4 atIndex:5]; call.target = NSClassFromString(className); [call invoke]; 
+3
source

Source: https://habr.com/ru/post/1494051/


All Articles