in xcode6 gold master, using objc_msgSend now thro

2019-01-22 13:45发布

 id<MyProtocol> topLayoutGuideObj = objc_msgSend(viewController, @selector(myselector));

"Too many arguments to function call, expected 0, have 2"

However, the function signature for objc_msgSend looks like this:

#if !OBJC_OLD_DISPATCH_PROTOTYPES
OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ )
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
#else
/** 
 * Sends a message with a simple return value to an instance of a class.
 * 
 * @param self A pointer to the instance of the class that is to receive the message.
 * @param op The selector of the method that handles the message.
 * @param ... 
 *   A variable argument list containing the arguments to the method.
 * 
 * @return The return value of the method.
 * 
 * @note When it encounters a method call, the compiler generates a call to one of the
 *  functions \c objc_msgSend, \c objc_msgSend_stret, \c objc_msgSendSuper, or \c objc_msgSendSuper_stret.
 *  Messages sent to an object’s superclass (using the \c super keyword) are sent using \c objc_msgSendSuper; 
 *  other messages are sent using \c objc_msgSend. Methods that have data structures as return values
 *  are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret.
 */
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

The arguments are "void" or variadic ?! I don't understand how I'm supposed to call this.

标签: ios xcode6
3条回答
ら.Afraid
2楼-- · 2019-01-22 14:34

if it happens in a cocoapod lib you just need to update to cocoapods 36.1 at least.If you can't do that add the following code at the end of your podfile:

(replace AFNetworking with the pod where you see those errors)

when /AFNetworking/            
    target.build_configurations.each do |config|
        config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = "NO"
end
查看更多
等我变得足够好
3楼-- · 2019-01-22 14:35

I have checked it out, the main problem was as @Jerry Krinock said in comment of accepted answer;

  1. Go to your project Build Settings
  2. Search for objc_msgSend
  3. Set its value to "No" instead of "Yes"
查看更多
forever°为你锁心
4楼-- · 2019-01-22 14:36

See just a few lines above you referred.

 /* 
  * ...
  *
  * These functions must be cast to an appropriate function pointer type 
  * before being called. 
  */

You can call it like:

#import <objc/runtime.h>
#import <objc/message.h>

id<MyProtocol> topLayoutGuideObj = ((id (*)(id, SEL))objc_msgSend)(viewController, @selector(myselector));

OR

id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
id<MyProtocol> topLayoutGuideObj = typed_msgSend(viewController, @selector(myselector));
查看更多
登录 后发表回答