getArgument of NSInvocation of current method always returns null

为君一笑 提交于 2019-12-24 19:14:59

问题


I want to get the name of the arguments of the current function I am in so that I can prepare loading that object from the filesystem if it's not present on the current instance. (for instance if [foo dictTest] is not available I want to load it's prior saved plist version into exactly that ivar)

I want to find the file by providing the ivar name that I provided as an argument to the current function.

This is the function code:

-(NSDictionary*)getCachedDictionary:(NSDictionary*)dict{

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:_cmd]];
    NSString * firstArgument = nil;
    [invocation getArgument:&firstArgument atIndex:2];
    NSLog(@"Trying to get the objects ivar %@",firstArgument);

    // right now during testing return nil
    return nil;
   }

As soon as the code reaches the NSLog I am getting a null value from firstArgument.

Why is that? Could it be possible that I would have to wait for the complete invocation of that current method I am in or is it actually better to create a proxy function that implicitly calls my class method via an invocation that eats the ivar name provided by setArgument so that I can use that argument string like I want?

Thanks a lot in advance!

P.S.: In this particular example I do not want to use KVC to identify the ivar and return it.


回答1:


You've misunderstood the NSInvocation API. +[NSInvocation invocationWithMethodSignature:] creates a new NSInvocation that is keyed to accept arguments of the types defined by the method signature. It does not return an NSInvocation that corresponds to the current method invocation. This is pretty easy to see why:

- (void)doBar:(id)bip {
  NSLog(@"hi there!")
}

- (void)doFoo {
  NSMethodSignature *sig = [self methodSignatureForSelector:@selector(doBar:)];
  NSInvocation *i = [NSInvocation invocationWithMethodSignature:sig];
}

When you create the invocation in doFoo for the doBar: method, it's obvious to see that the arguments must be empty, because doBar: hasn't been executed, and thus there is no argument. Changing @selector(doBar:) to _cmd wouldn't magically change anything.

So the next question: is there a way to get an NSInvocation for the current method invocation? Not that I know of. NSInvocation is an extremely complicated class, and constructing one from the current method would be a nightmare.

I strongly suggest finding a different approach to do whatever it is you want to do.




回答2:


Even though the question is old and answered, here is a link that provides an easy and very elegant way to create an invocation instance for any selector/method that is known at compile time:

http://www.cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html



来源:https://stackoverflow.com/questions/9053574/getargument-of-nsinvocation-of-current-method-always-returns-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!