简体   繁体   中英

What's better practice: objc_msgSendv or NSInvocation?

So I'm working on something in obj-c (I'd rather not say what) where I need to be able to call arbitrary methods on arbitrary objects with arbitrary variables. The first two are easy enough to do, but I am unsure how to do the variable arguments. To be clear, this is not about a function/method receiving variable arguments, but about sending them. I have found two ways to do this: objc_msgSendv (and its variants) in the objective-c runtime, and NSInvocation. NSInvocation seems easier and more like it's the 'best practice', but objc_msgSendv sounds like it should be faster, and I need to do this many, many times over, with completely different messages each time. Which one should I choose? Is objc_msgSendv taboo for a good reason? (the docs say not to call the objc_msgsend functions.)

PS I know the types of all the arguments, and not all of them are id-s

Also, (not part of the main question,) there doesn't appear to be a way to message super from objc_msgSendv, but there doesn't seem to be a way to do that in NSInvocation either, so any help on that would be great too.

objc_msgSendv is deprecated; is unavailable entirely in 64 bit Mac OS X apps. So, regardless, don't use it.

The real question is whether or not you know the argument set at compile time or not. If so, use objc_msgSend (or appropriate variant).

If not, then you are going to have to use some mechanism to encode the arguments into a call compliant with the C ABI specific to your particular target architecture(s). NSInvocation is the easiest means of doing so, but you are correct in that there is overhead.

You could drop down to libffi to gain a touch of efficiency, but there is still a huge amount of overhead building your own calls vs. letting the compiler compile a bit of code.

If you have a finite # of combinations of argument and return types, you could compile a bunch of trampoline functions and use those.

Actually, the real question is "What are you trying to do?" What you describe is fairly atypical. Not that you might likely not have a very good reason, just that whatever it is is very interesting (to me, anyway)!

Beware premature optimization. I would start with the higher-level functionality (NSInvocation) because it will be easier to unit test, code, and debug. Then take measurements. Move to lower-level functionality (objc_msgSendv) only if your measurements show a significant amount of time spent in and around the NSInvocations (such as preparing them). Otherwise, even if objc_msgSendv is faster, you will receive no observable benefit, at the cost of code that is harder to maintain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM