2013-11-24 8 views
5

मेरे पास कक्षा iOS प्रोजेक्ट में है जो Objective-C और C कोड उसी कक्षा में लागू करती है। मैंने एक्सटेंशन को .mm में बदल दिया और यह हिस्सा अच्छी तरह से चला गया। अब मैं C विधि सेट करना चाहता हूं जो उसी कक्षा में Objective-C विधि को कॉल करेगा। मुझे मिलने वाली समस्या यह है कि जब मैं विधि से self पर कॉल करने का प्रयास कर रहा हूं।सी विधि से उद्देश्य-सी "स्वयं" को कैसे कॉल करें

void SetNotificationListeners(){ 
    [self fireSpeechRecognition]; 
} 

त्रुटि है:

Use of undeclared identifier 'self' 

मैं यह कैसे प्रबंधित कर सकते हैं यहाँ कोड है?

+0

यह आईओएस है, आईओएस नहीं। वैसे भी, आप एक ऐसे कार्य के भीतर से 'स्वयं' को कैसे पहुंचने की उम्मीद करते हैं जो ** ** ** कक्षा से संबंधित नहीं है? यह सिर्फ समझ में नहीं आता है। आपको एक तर्क के रूप में उदाहरण (ऑब्जेक्ट) में खुद को पास करने की आवश्यकता होगी। –

+2

जब आप उद्देश्य-सी और सी का उपयोग कर रहे हैं तो आप एक्सटेंशन को '.mm' में क्यों बदल चुके हैं (आप C++ का उल्लेख नहीं करते हैं)? – trojanfoe

उत्तर

10

उपयोग कर रहे हैं आप है सी समारोह के लिए उदाहरण के सूचक पारित करने के लिए .mm को फाइल एक्सटेंशन को बदलने की जरूरत नहीं है:

void SetNotificationListeners(void *uData) 
{ 
    MyClass *obj = (__bridge MyClass *)(uData); 
    [obj fireSpeechRecognition]; 
} 

- (void)myMethod 
{ 
    // Call C function from Objective-C method: 
    myFunction((__bridge void *)(self)); 
} 

("Brigde" सामान केवल तभी जरूरी है जब आप एआरसी के साथ संकलित हों।)

+0

इस पोस्ट को पढ़ना मैं पूछता हूं, सी में आप उद्देश्य सी कहां कहते हैं? यहां आपने कहा "उद्देश्य सी से कॉल सी फ़ंक्शन" ... समझ में नहीं आता ... यह मुझे भ्रम बना देता है! रु –

0

या तो समारोह कॉल करने के लिए एक तर्क के रूप स्वयं दे:

void SetNotificationListeners(void *myObj){ 
[(MyClass*)myObj fireSpeechRecognition]; 
} 

//in objC 
SetNotificationListeners(self); 

या एक वैश्विक चर कि संदर्भ

//global variable 
static MyClass *myObj; 

//in obj c 
myObj = self; 
SetNotificationListeners(); //use myObj instead of self in function 

पहले मेरी राय में बेहतर है रखती है।

+3

दूसरा पागलपन है :) – zoul

+0

जैसा कि मैंने कहा था कि आईडी पहला विकल्प पसंद करता है। मजेदार कैसे मैं मतदान करता हूं जब अब इस प्रश्न के डुप्लिकेट में 10 अप वोटों के साथ चिह्नित उत्तर में केवल "पागलपन" का उल्लेख किया गया है .... – Mario

1

उद्देश्य-सी विधियों में दो पैरामीटर हैं जो प्रत्येक विधि में निहित रूप से पारित होते हैं, जो self और _cmd हैं। यही कारण है कि आप एक विधि के भीतर से self तक पहुंच सकते हैं।

ऑब्जेक्टिव-सी विधि से कॉल करते समय आप अपने सी फ़ंक्शन के लिए तर्क के रूप में self पास कर सकते हैं, लेकिन उस छोटे उदाहरण के साथ मुझे यकीन नहीं है कि आप केवल एक विधि का उपयोग क्यों नहीं करेंगे।

आप जब तक आप ऑब्जेक्टिव-सी ++

2

आपको फ़ाइल एक्सटेंशन को बदलने की आवश्यकता नहीं है। उद्देश्य-सी सी का एक सुपरसेट है, जिसका अर्थ है कि आप अपने उद्देश्य-सी फाइलों में सादे सी का उपयोग कर सकते हैं।

जब आप एक ऑब्जेक्टिव-सी विधि के एक कार्यान्वयन लिखते हैं, कि विधि हमेशा कुछ विशेष उदाहरण के संदर्भ में कार्यान्वित करता है, कि self हिस्सा है। आपको स्वचालित रूप से उद्देश्य-सी विधि में self मिलते हैं, लेकिन दृश्यों के पीछे यह विधि के लिए तर्क के रूप में पारित किया गया है, obc_msgsend देखें।

आपका सादा सी फ़ंक्शन कक्षा का हिस्सा नहीं है (सादा सी कार्य कभी नहीं होते हैं), इसलिए जब आप इसे कॉल करते हैं तो इसके साथ कोई उदाहरण नहीं जुड़ा होता है, कोई अंतर्निहित self नहीं है। यदि आप फ़ंक्शन को कुछ उदाहरण कॉल करना चाहते हैं, तो आपको उस उदाहरण में पॉइंटर को स्पष्ट रूप से पास करना होगा। उदाहरण के लिए कुछ सादे सी एपीआई में एक "संदर्भ" सूचक होता है जिसे आप कॉलबैक के लिए पंजीकरण करते समय पास कर सकते हैं। इसके उदाहरणों के लिए पड़ोसी उत्तर देखें।

संबंधित मुद्दे