2011-08-07 13 views
21
@implementation ThisObject 

-(void)start { 

     SomeOtherObject *someOtherObject = [SomeOtherObject alloc]; 

     [someOtherObject doSomethingAndCallThisFunctionWhenUrDone:myCallBackFunction :self]; 

} 

-(void)myCallBackFunction { 

     // :) 

} 

असल में, मैं कैसे यह काम कर सकते हैं?उद्देश्य सी में सी में फ़ंक्शन पॉइंटर पास करने के बराबर क्या है?

+0

लेकिन इसके बारे में SomeOtherObject की तरफ क्या है? SomeOtherObject में क्या घोषित करने की आवश्यकता है और इसे करने की क्या आवश्यकता है? इसे एक ऐसा करना होगा और कॉल करें यह कार्यक्षमता WhenUrDone। लेकिन यह ऑब्जेक्ट ऑब्जेक्ट के लिए कहा गया विधि कहने के लिए वास्तव में क्या करना है? बीटीडब्ल्यू thx अब तक एक लाख। – Joe

+0

मैंने कुछ और कार्यान्वयन विवरण दिखाने के लिए अपना जवाब विस्तारित किया। फ़ंक्शन पॉइंटर्स और ब्लॉकों के लिए आपको उन्हें कॉल करने के लिए किसी ऑब्जेक्ट की आवश्यकता नहीं है, लेकिन आप ऑब्जेक्ट्स को तर्क के रूप में पास कर सकते हैं। – rbrown

उत्तर

3

क्या आप इस बारे में बात कर रहे हैं?

-(void)callSomePassedSelector:(SEL)callbackSelector { 
    [someObjectThatRespondesToThisSelector performSelector:callbackSelector]; 
} 

मैं तुम्हें यह स्टोर और इसे बाद में कॉल करना चाहते हैं मान, लेकिन यह आप कैसे गुजरती हैं और इसे कहते हैं के बारे में सभी आवश्यक जानकारी देना चाहिए। वहाँ अन्य तरीकों चयनकर्ता आह्वान करने के लिए कर रहे हैं, अधिक here

+0

तब आप चयनकर्ता में कैसे पास करेंगे? – TheJeff

0

im थोड़ा तुम क्या बारे में बात कर के बारे में उलझन को देखने के, लेकिन यह यह क्या है?

[self performSelector:@selector(myCallFunction)]; 
49

वहाँ एक कॉलबैक बनाने के लिए चार तरीके हैं:

  1. समारोह सूचक आप एक समारोह सूचक कर सकते हैं यदि आप वास्तव में चाहते हैं, लेकिन यह अनुशंसित नहीं है। यह वैसे ही किया जाता है जैसा आप सी में करेंगे। समस्या यह है कि आप एक उद्देश्य सूचक विधि में फ़ंक्शन पॉइंटर का उपयोग नहीं कर सकते हैं। यह इस तरह दिखता है:

    void callback(/* Some args */) { 
        // Some callback. 
    } 
    
    - (void)doSomethingAndCallThisFunctionWhenDone:(void(*)(/* Some args */))func { 
    
        // Do something. 
    
        if (func) 
         func(/* Some args */); 
    } 
    
    - (void)start { 
        [self doSomethingAndCallThisFunctionWhenDone:&callback]; 
    } 
    
  2. चयनकर्ता आप -performSelector उपयोग कर सकते हैं :. यह इस तरह दिखता है:

    - (void)doSomethingAndCallTarget:(id)target withSelector:(SEL)sel { 
    
        // Do something. 
    
        [target performSelector:sel]; 
    } 
    
    - (void)start { 
    
        SomeOtherObject * someOtherObject = [[SomeOtherObject alloc] init]; 
    
        [self doSomethingAndCallTarget:someOtherObject withSelector:@selector(MyCallback)]; 
    } 
    
  3. प्रतिनिधियों उपयोग एक प्रतिनिधि। यह UITableViewDelegate/UITableViewDataSource के समान है। Apple docs here देखें। आप इसे इस तरह कर सकते हैं:

    - (void)doSomethingDelegate:(id<MyCallbackObject>)delegate { 
    
        [delegate retain]; 
    
        // Do something. 
    
        [delegate performMyCallback]; // -performMyCallback must be declared in the MyCallbackObject protocol and implemented by SomeOtherObject. 
    
        [delegate release]; 
    } 
    
    - (void)start { 
    
        id<MyCallbackObject> someOtherObject = [[SomeOtherObject alloc] init]; 
    
        [self doSomethingDelegate:someOtherObject]; 
    
        [someOtherObject release]; 
    } 
    
  4. ब्लाकों पसंदीदा तरीका कॉलबैक के लिए ब्लॉकों का उपयोग करें। वे केवल आईओएस 4.0+ या मैक ओएस एक्स 10.6+ के लिए उपलब्ध हैं। यह इस तरह दिखता है:

    - (void)doSomethingAndCallThisBlockWhenDone:(void(^)(/* Some args */))block { 
    
        [block copy]; 
    
        // Do something. 
    
        if (block) 
         block(/* Some args */); 
    
        [block release]; 
    } 
    
    - (void)start { 
        [self doSomethingAndCallThisBlockWhenDone:^void(/* Some args */){ // Return type and arguments may be omitted if you don't have any. 
         // Your callback 
        }]; 
    } 
    

आप ब्लॉक के साथ देख सकते हैं, इसे पढ़ने के लिए आसान है और अपने कॉलबैक अपने कोड के साथ इनलाइन है। यह विशेष रूप से अच्छा है इसलिए आपको इसे शिकार करने की ज़रूरत नहीं है। ब्लॉक के कई और फायदे हैं, लेकिन मैं उन्हें यहां सभी को कवर नहीं कर सका।

यदि आप ब्लॉक का उपयोग करते हैं तो एक आखिरी बात, आप typedef का उपयोग करना चाहेंगे, इसलिए आपको हर समय void(^)(/* Some args */) जैसे अस्पष्ट ब्लॉक प्रकार टाइप करने की आवश्यकता नहीं है। तब

typdef void(^MyCallback)(/* Some args */); 

, तो आप इस तरह अपने प्रणाली की घोषणा कर सकते हैं:: typedef ऐसा दिखाई दे सकता

- (void)doSomethingAndCallThisBlockWhenDone:(MyCallback)block; 

अद्यतन:

मैं कैसे अलग लागू करने के लिए की और अधिक विस्तार से पता चला है तकनीकें (ऊपर देखें)।

+1

+1 अच्छा व्यापक जवाब। याद रखें कि यदि आपको रनलॉप की वर्तमान बारी से परे या अलग-अलग धागे पर बने रहने के लिए ब्लॉक की आवश्यकता है, तो उसे ढेर में कॉपी करने की आवश्यकता है (या आप एआरसी के साथ संकलित करते हैं और यह सही चीज ™ करता है) –

+0

धन्यवाद डेव। मैं उस विवरण को जोड़ना भूल गया। यह अब वहां है। – rbrown

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