2010-04-07 24 views
6

मैं सिमबेल का उपयोग करके प्लगइन लिखना सीखने की कोशिश कर रहा हूं। मुझे लक्ष्य प्लगइन के साथ लोड करने के लिए मेरी प्लगइन मिल गई है, और यह तरीका भी पता है कि मैं ओवरराइड करना चाहता हूं। हालांकि, मैं इंटरनेट पर स्निपेट के आधार पर class_getInstanceMethod का सही ढंग से उपयोग करने में सक्षम नहीं हूं। ओएसएक्स 10.6 और/या ओबीजेसी 2 में चीजें बदली हैं?ObjC2 में विधि कार्यान्वयन को गतिशील रूप से कैसे बदलें?

culater.net से निम्नलिखित कोड दूसरी पिछले विवरण पर "अधूरा प्रकार के अपसंदर्भन सूचक" देता है:

BOOL DTRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector) 
{ 
    Method method = nil; 

    // First, look for the methods 
    method = class_getInstanceMethod(_class, _oldSelector); 
    if (method == nil) 
     return NO; 

    method->method_name = _newSelector; 
    return YES; 
} 

वहाँ कैसे एक विधि SIMBL प्लग इन का उपयोग ओवरराइड करने के लिए की एक पूरी उदाहरण है? धन्यवाद!

उत्तर

5

यदि आप swizzle a method पर देख रहे हैं, तो आप इसके बजाय the method_exchangeImplementations function का उपयोग करने पर विचार कर सकते हैं।

+0

यह काम किया। धन्यवाद! – Abhi

+0

पीटर - क्या यह 'फ़ंक्शन स्विजलिंग' करना भी संभव है, यानी किसी ऐसे फ़ंक्शन के कार्यान्वयन को प्रतिस्थापित करना जो कक्षा की विधि नहीं है? – Abhi

+2

नहीं। विधि स्विजलिंग काम करता है क्योंकि चयनकर्ता के लिए कार्यान्वयन गतिशील रूप से उस समय को देखा जाता है जब आप संदेश भेजते हैं-i.e।, रन टाइम पर। एक नाम है, जो चयनकर्ता है, और एक मान, जो कार्यान्वयन है, और स्विजलिंग एक दूसरे के लिए एक मान स्वैप करता है, एक शब्दकोश में बदलते मूल्यों के विपरीत नहीं। कार्य गतिशील रूप से नहीं देखा जाता है; निष्पादन योग्य लोड होने पर पता बाध्य हो जाता है और उसके बाद तय रहता है, और कॉल सीधे उस पते पर जाती है, इसलिए रीमेप करने के लिए कुछ भी नहीं है। –

7

ऑब्जेक्ट-सी 2 में ओब्जे-सी रनटाइम बदल गया है, आपके द्वारा उद्धृत कोड पुराने का उपयोग करता है।

(ठीक है, 32 बिट ऐप्स पर, यह कहना सही है कि एक ही रनटाइम में दो इंटरफेस हैं, इस पर निर्भर करते हुए कि आप अपनी बाइनरी कैसे संकलित करते हैं; अंत में दोनों काम करते हैं। लेकिन यह सोचना आसान है कि चीजें बदल गईं उद्देश्य-सी 2. और आपको नए एपीआई का उपयोग करना चाहिए क्योंकि इसका उपयोग करना आसान है, और यह 32 बिट और 64 बिट दोनों में काम करता है।)

नए संदर्भ the Guide और the Reference हैं। मूल परिवर्तन यह है कि आंतरिक struct अब सार्वजनिक नहीं है, अपारदर्शी है। तो आप सीधे अपने सदस्य तक नहीं पहुंच सकते हैं। इसके बजाय, आपको एक एपीआई का उपयोग करने की आवश्यकता है।

आमतौर पर नए रनटाइम में चीजें आसान होती हैं। एक IMP बदलने के लिए, एक बस

IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types); 

का उपयोग करता है प्रकार एन्कोडिंग पाने के लिए, मूल विधि बदल रहे हैं के खिलाफ

const char * method_getTypeEncoding(Method method); 

का उपयोग करें। अभ्यास में, कि

method_getTypeEncoding(class_getInstanceMethod([SomeClass class], @selector(someSelector:you:want:to:replace:))); 

क्रम के बारे में अधिक जानने के लिए हो सकता है, मैं दिल से ब्लॉग पोस्ट Friday Q&A माइक ऐश द्वारा की अद्भुत श्रृंखला सलाह देते हैं।

मज़ेदार और शुभकामनाएँ!

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