2014-09-15 5 views
16
id<MyProtocol> topLayoutGuideObj = objc_msgSend(viewController, @selector(myselector)); 

है एक सिंटैक्स त्रुटि फेंकता है "अत्यधिक तर्क कॉल कार्य करने के लिए, उम्मीद 0, 2", अब objc_msgSend का उपयोग कर कह तर्क की संख्या गलत

हालांकि, objc_msgSend के लिए समारोह हस्ताक्षर ऐसा लगता है:

#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); 

तर्क "शून्य" या भिन्न हैं? मुझे समझ में नहीं आता कि मुझे यह कैसे कहना है।

+1

उत्सुक क्यों आप आसानी से '[viewController mySelector] को कॉल नहीं करते हैं; '। – rmaddy

+1

उचित सवाल। मैंने यह कोड नहीं लिखा है, मैं बस इसे ठीक करने की कोशिश कर रहा हूं - और जितना संभव हो उतना छोटा बदल सकता हूं। हालांकि, मैं केवल – nont

+0

आईओएस 8 जीएम और एक्सकोड 6 जीएम एनडीए के तहत कर रहा हूं, ऐप्पल डेवलपर्स फोरम या ऐप्पल टेक सपोर्ट का प्रयास कर सकता हूं। –

उत्तर

26

आपके द्वारा संदर्भित कुछ पंक्तियों को देखें।

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

आप इसे पसंद कॉल कर सकते हैं:

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

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

या

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

जाहिर है, एक्सकोड 6 में यह क्यों दिखाई देता है क्योंकि चेतावनी "objc_msgSend कॉल की सख्त जांच सक्षम करें" अब डिफ़ॉल्ट रूप से सक्षम है, और जब आप पुरानी प्रोजेक्ट खोलते हैं और "अनुशंसित सेटिंग्स पर प्रोजेक्ट अपडेट करते हैं" डिफ़ॉल्ट रूप से स्विच किया जाता है। –

+1

objc_msgSendSuper() के लिए एक समान फिक्स की आवश्यकता है। रिंटारो के दूसरे उदाहरण के बाद, जवाब है: आईडी (* typed_msgSendSuper) (संरचना objc_super *, SEL, ...) = (शून्य *) objc_msgSendSuper; वापसी वैल्यू = typed_msgSendSuper (& yourSuperStruct, yourSelector, yourFirstArg, ...); –

10

मैं इसे बाहर की जाँच कर ली, मुख्य समस्या यह थी के रूप में @Jerry Krinock स्वीकार किए जाते हैं जवाब की टिप्पणी में कहा,

  1. objc_msgSend
  2. अपने मूल्य सेट के लिए सेटिंग्स का निर्माण अपनी परियोजना के लिए जाओ
  3. खोजें "नहीं" के बजाय "हाँ" के लिए
+1

ऐसा मत करो। एक कारण के लिए चेतावनी मौजूद है; बिना टाइप-कास्टिंग objc_msgSend() के पैरामीटर के विशेष रूप से टाइप किए गए सेट को आप पास करना चाहते हैं, यह कुछ एबीआई पर काम नहीं करेगा। Varargs स्पष्ट रूप से टाइप की गई पैरामीटर सूची के समान नहीं है। – bbum

+1

@bbum के कहने के लिए एक उदाहरण के रूप में, जब आप varargs के माध्यम से 'char' (या' BOOL', जो टाइप करने के लिए टाइप टाइप करते हैं) को पास करते हैं, तो इसे एक int में प्रचारित किया जाता है, जो यह नहीं है कि आप फ़ंक्शन को टाइपकास्ट करते हैं वास्तव में यह टाइप करें। एक नियमित कॉल वर्णों को बढ़ावा नहीं देती है, इसलिए यदि आप चेतावनी बंद कर देते हैं, तो आपको यह पता नहीं चलता है कि आप अपने कार्य में यादृच्छिक कचरा पारित करते समय महसूस नहीं करते हैं। – uliwitness

1

अगर यह एक cocoapod में होता है lib तुम सिर्फ करने की जरूरत है least.If पर cocoapods 36.1 करने के लिए अद्यतन आप देखेंगे कि आपके podfile के अंत में निम्न कोड जोड़ नहीं कर सकते:

(जहां आप उन त्रुटियों को देखने फली साथ AFNetworking की जगह)

when /AFNetworking/    
    target.build_configurations.each do |config| 
     config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = "NO" 
end 
संबंधित मुद्दे