2012-02-02 10 views
9

मुझे पता है कि आप कक्षा के बाहर एक सी फ़ंक्शन घोषित कर सकते हैं, लेकिन क्या कक्षा के बाहर एक उद्देश्य-सी विधि घोषित करना संभव है?क्या कक्षा के बाहर एक उद्देश्य-सी विधि घोषित करना संभव है?

उदाहरण:

// Works 
void printHelloC() 
{ 
    NSLog(@"Hello."); 
} 

// Error 
-(void) printHelloOC 
{ 
    NSLog(@"Hello."); 
} 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     printHelloC(); 
     [self printHelloOC];// 'self' obviously would not work but you get the idea 
    } 
    return 0; 
} 

उत्तर

4

यह निर्भर करता है। आप विधि कार्यावधि में जोड़ने के साथ कुछ ऐसा ही कर सकते हैं:

#import <objc/runtime.h> 

void myCustomMethod(id self, SEL _cmd, id arg1, id arg2) 
{ 
    NSLog(@"This is a test, arg1: %@, arg2: %@", arg1, arg2); 
} 

int main(int argc, char *argv[]) 
{ 
    Class NSObjClass = [NSObject class]; 

    class_addMethod(NSObjClass, @selector(myNewMethod::), (IMP) myCustomMethod, "[email protected]:@@"); 

    NSObject myObject = [NSObject new]; 

    [myObject myNewMethod:@"Hi" :@"There"]; 

    [myObject release]; 

    return 0; 
} 

लेकिन यह एक @class निर्माण के बाहर इसके बारे में है, और यह वास्तव में सिर्फ क्या एक वर्ग के साथ होता है को शामिल किया गया।

+0

अच्छा जवाब, लेकिन आपका विधि नाम एक गलत नामक है, क्योंकि यह वास्तव में एक विधि नहीं है जो चयनकर्ता – dreamlax

+0

@dreamlax अच्छा बिंदु, निश्चित –

0

एक विधि एक संबद्ध वर्ग के बिना एक अर्थहीन अवधारणा है। जैसा कि आपने ध्यान दिया है, कार्य ठीक हैं।

+5

आवश्यक नहीं है। आपके पास एक चयनकर्ता हो सकता है जो वस्तु के अनुसार स्वतंत्र कोड को निष्पादित करता है, जब तक कि यह एक निश्चित कार्य करता है। प्रोटोकॉल के पीछे यही कारण है। –

+0

@ रिचर्ड जे। रौसीआईआई - जो कुछ आप वर्णन करते हैं वह करने के लिए निश्चित रूप से आप 'एनएसओब्जेक्ट' पर * श्रेणी * परिभाषित करते हैं? – CRD

+0

@CRD जरूरी नहीं है, आप विधि जोड़ के साथ एक ही काम कर सकते हैं (मेरा जवाब देखें)। मूल रूप से एक श्रेणी क्या करने का एक और जटिल तरीका है। –

4

इसके लिए आप श्रेणी का उपयोग कर सकते हैं।

एक उदाहरण विधि के रूप में:

@interface NSObject (MONStuff) 
- (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
- (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

NSObject * obj = ...; 
[obj printHelloOC]; 

एक कक्षा विधि के रूप में:

@interface NSObject (MONStuff) 
+ (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
+ (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

[NSObject printHelloOC]; 
बेशक

, आपको लगता है कि सहयोगी एक वर्ग के साथ करना होगा - तो यह बिल्कुल नहीं है जैसा कि आपने पोस्ट किया है, लेकिन यह एक करीबी परिभाषा है + घोषणा औपचारिक कक्षा घोषणा से अलग है।

+0

एक श्रेणी केवल कक्षा को विस्तारित करती है - परिभाषा के अनुसार श्रेणी में घोषित किसी भी तरीके कक्षा में हैं ... –

+0

@ करल मैंने इसे विस्तारित किया – justin

+0

आपकी नई विधि एक 'एनएसएसटींग' विधि है। यह कक्षा के बाहर नहीं है - वह * अंदर * 'NSString' है! –

0

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

@interface Test 

+ (void)aClassMethod; 

@end 

तो आप इसे फोन करके कॉल कर सकते हैं लिख सकते हैं

[Test aClassMethod]; 
+2

हमेशा सत्य नहीं है। उदाहरण के लिए यदि आप विधि swizzling का उपयोग करते हैं, तो आप एकाधिक चयनकर्ताओं के साथ एकाधिक कक्षाओं में एक फ़ंक्शन जोड़ सकते हैं! –

+0

शायद ...लेकिन विधि swizzling एक सुंदर उन्नत अवधारणा है, और निश्चित रूप से ऐसा कुछ नहीं है जिसे आपको सावधानीपूर्वक विचार किए बिना चाहिए। – futureelite7

+0

यह जटिल नहीं है, आप बस रनटाइम को शामिल करते हैं, अपना फ़ंक्शन बनाते हैं, और चयनकर्ता के साथ कक्षा में विधि जोड़ते हैं। यह रॉकेट वैज्ञानिक को करने के लिए नहीं लेता है, और विधि कार्यान्वयन स्वैपिंग इतना आसान है। –

0

नहीं, यह संभव नहीं है - आपको या तो वैश्विक सी कार्यों या कक्षा (+) विधियों का उपयोग करने की आवश्यकता होगी।

+1

यह संभव है, उद्देश्य-सी रनटाइम आपको कक्षा में विधियों को जोड़ने की अनुमति देता है जबकि कार्यक्रम निष्पादित कर रहा है। यह आपको पूरी नई कक्षाएं बनाने की अनुमति देता है। आप एक उद्देश्य-सी विधि कार्यान्वयन को परिभाषित कर सकते हैं और फिर उस विधि को कक्षा और चयनकर्ता के साथ जोड़ सकते हैं। – dreamlax

+0

हां, गतिशील रूप से कक्षाएं बनाना वास्तव में संभव है। यह सवाल नहीं है, हालांकि। सवाल यह है कि ऑब्जेक्टिव-सी विधियों को ला-ए ग्लोबल सी फ़ंक्शंस को परिभाषित करना और निष्पादित करना संभव है (या, वैश्विक स्तर पर जावास्क्रिप्ट बंद हो गया है)। यह संभव नहीं है। उद्देश्य-सी विधियों को कक्षा (वर्ग या उदाहरण स्कॉप्ड) के हिस्से के रूप में परिभाषित किया जाना चाहिए। –

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