2012-05-03 7 views
9

बस ब्लॉक पर एक संभाल पाने की कोशिश कर रहा है। मुझे अवधारणा मिलती है। वे फ़ंक्शन पॉइंटर्स की तरह हैं, लेकिन वे वास्तव में ऑब्जेक्ट्स हैं; आप ब्लॉक वैरिएबल घोषित कर सकते हैं और इसे ब्लॉक मान असाइन कर सकते हैं; इसे एक समारोह की तरह बुलाओ; वे एक शब्द की कमी के लिए "समय में जमे हुए" होते हैं, जब उन्हें निष्पादित किया जाता है, आदि। मैंने कुछ ब्लॉक बनाए हैं और उन्हें कुछ अलग प्रारूपों में सफलतापूर्वक चलाया है, लेकिन जब उन्हें किसी विधि में उपयोग करने की बात आती है- या तो टाइप किए गए या बिना - मुझे बहुत परेशानी हो रही है। उदाहरण के लिए, सिंटैक्स पर एक हैंडल प्राप्त करने के लिए, मैंने बनाया एक ऑब्जेक्ट इंटरफ़ेस यहां दिया गया है। मुझे लगभग कोई जानकारी नहीं है कि इसे कैसे कार्यान्वित किया जाए।उद्देश्य-सी: typedef'd एक ब्लॉक, इसे एक विधि घोषणा में इस्तेमाल किया। मैं इसे कैसे क्रियान्वित करूं?

// AnObject.h 

#import <Foundation/Foundation.h> 

// The idea with the block and the method below is for the block to take 
// an int, multiply it by 3, and return a "tripled" int. The method 
// will then repeat: this process however many times the user wants via 
// the howManyTimes parameter and return that value in the form of an int. 

typedef int (^triple)(int); 

@interface AnObject : NSObject 
{ 
    int num; 
} 

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock; 

@end 

यहाँ है कि मैं क्या एक कार्यान्वयन के लिए राशि है, अब तक:

#import "AnObject.h" 

@implementation AnObject 

@synthesize num; 

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock { 
    for (int i = 0; i <= howManyTimes; i++) { 
     // What the heck am I supposed to put here? I'm baffled by the 
     // syntax over and over again. 
    } 
} 

@end 

मैं जानता हूँ कि मैं अभी तक उदाहरण चर को संबोधित नहीं कर रहा हूँ। फिर, यह एक मोटा मसौदा है, बस ब्लॉक कैसे काम करता है पर एक संभाल पाने की कोशिश कर रहा है। क्या मैं इस विधि को सही घोषित कर रहा हूं? मैं बिग नेर्ड रांच के ऑब्जेक्टिव-सी प्रोग्रामिंग, माइक क्लार्क का आलेख प्रोगामैटिक स्टूडियो से ब्लॉक पर और कई एसओ धागे पढ़ रहा हूं। कुछ भी प्रासंगिक नहीं मिल रहा है। धन्यवाद।

संपादित करें: एक्सकोड 4.3.2, यदि यह महत्वपूर्ण है।

और संपादित करें: ठीक है। बी.जे. के (थोड़ा संशोधित) उदाहरण का उपयोग करना, मुझे लगता है कि मैं 3. :)

// BJ's implementation: 

-(int)repeat:(int)howManyTimes withBlock:(Triple)someBlock { 

    int blockReturnValue; 

    for (int i = 0; i <= howManyTimes; i++) { 
     blockReturnValue = someBlock(i); 
    } 
    return blockReturnValue; 
} 

मुख्य से गुणा 5 का एक बहुत जटिल तरीके से ले कर आए हैं:

... 
    @autoreleasepool 
    { 
     AnObject *obj = [[AnObject alloc] init]; 

     NSLog(@"%d", [obj repeat: 5 withBlock:^(int number) { 
      return number * 3; 
     }]); 

    } 
    return 0; 
... 

और उत्पादन होता है:

15 

अब, यह 15 वापस लात मार रहा है, क्योंकि एक तर्क के रूप में परिभाषित ब्लॉक केवल एक बार चलाया जाता है, है ना? यह "संख्या" से गुणा करता है, जो इस मामले में 5 है, 3 से और उस उत्तर को फ्रीज करता है, है ना? मुझे यकीन है कि मैंने अभी एक पूरी तरह से बेकार विधि बनाई है, और मुझे अभी तक समझ में नहीं आता कि ब्लॉक के लाभ/सुविधाओं का उपयोग कैसे किया जाए। क्या मैं सही हूँ?

/* ** * ** * ** * ** * ** * ** * ** अद्यतन ** * ** * ** * ** * ** * ** * ** */

अद्यतन: मैं समझता हूँ कि तुम क्या कह रहे हैं, CRD। बस एक सुधार हालांकि, किसी भी नए प्रोग्रामर के लिए जो इसे पढ़ रहे हैं, एक अलग आउटपुट प्राप्त कर रहे हैं, "क्यू?"

for (int i = 0; i < howManyTimes; i++) 
      value = someBlock(value); 

... या ...

(i = 1; i <= howManyTimes; i++) 

... जवाब 243 पाने के लिए: अपने लिए पाश या तो होना चाहिए।

और, हाँ, यह वही है जो मैं शुरू में इस कोड के साथ करने का प्रयास कर रहा था। कम से कम यही मैंने सोचा था कि क्या हो रहा था। लेखक का इरादा किसी संख्या को तीन गुना करने के लिए नहीं था, उस मूल्य को स्टोर करें, संग्रहीत मूल्य को तीन गुना करें, स्टोर करें ... आदि, बल्कि संख्या 1-5 (3, 6, 9, के लिए x * 3 मुद्रित करने के लिए, 12, 15)।

यहां तैयार उत्पाद है। मैंने बस एक ब्लॉक टाइप किया है जो एक int लेता है और एक इंटेल देता है, जिसे ट्रिपलर कहा जाता है। मैंने ब्लॉक के इच्छित उपयोग को और स्पष्ट रूप से इंगित करने के लिए "कुछब्लॉक" से "ट्रिपल" से तर्क का नाम भी बदल दिया। मुझे लगता है कि कोड में ये एकमात्र बदलाव हैं।

/******************** interface ********************/ 


#import <Foundation/Foundation.h> 

typedef int (^Tripler)(int); 

@interface AnObject : NSObject 

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple; 

@end 

/******************** implementation ********************/ 


#import "AnObject.h" 

@implementation AnObject 

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple { 
    for (int i = 1; i <= number; i++) { 
     NSLog(@"%d", triple(i)); 
    } 
} 

@end 

/******************** main.m ********************/ 


#import "AnObject.h" 
#import <Foundation/Foundation.h> 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool 
    { 
     AnObject *obj = [[AnObject alloc] init]; 

     [obj iterateFromOneTo:5 withBlock:^(int number) { 
      return number * 3; 
     }]; 
    } 
    return 0; 
} 

आप शायद कल्पना कर सकते हैं, जिसके परिणामस्वरूप उत्पादन होता है:

2012-05-05 17:10:13.418 Untitled 2[71735:707] 3 
2012-05-05 17:10:13.445 Untitled 2[71735:707] 6 
2012-05-05 17:10:13.446 Untitled 2[71735:707] 9 
2012-05-05 17:10:13.446 Untitled 2[71735:707] 12 
2012-05-05 17:10:13.447 Untitled 2[71735:707] 15 

मैं इसे बना रही थी एक बहुत अधिक जटिल की तुलना में यह हो सकता है की जरूरत है। ओपी में इसे इतनी खराब समझाने के लिए खेद है। आपकी सहायताके लिए धन्यवाद!/थ्रेड? :)

+0

इस ब्लॉक स्पष्टीकरण के माध्यम से जाओ ... http://www.highoncoding.com/Articles/852_Introduction_to_Objective_C_Blocks.aspx – shankar

उत्तर

7

बस नियमित सी फ़ंक्शन की तरह ब्लॉक को कॉल करें।

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock { 
    for (int i = 0; i <= howManyTimes; i++) { 
     int blockReturnValue = someBlock(i); 
     // do something with blockReturnValue 
    } 
} 

अद्यतन अपने "आगे संपादित करें"

पांच बार नहीं है, ब्लॉक आप एक तर्क के रूप में पारित कर दिया चलाया जाता है के बाद, प्रत्येक पाश के लिए के माध्यम से पारित।

  • पहली बार है, यह 1 तर्क के रूप में के साथ ब्लॉक का आह्वान, और वापस 3 हो जाता है। यह blockReturnValue में स्टोर करता है, फिर लूप के अगले पुनरावृत्ति पर जाता है।
  • दूसरी बार, यह तर्क के रूप में 2 के साथ ब्लॉक को आमंत्रित करता है, और 6 वापस आता है। यह स्टोर करता है कि blockReturnValue, पिछले पास में संग्रहीत मूल्य को पूरी तरह ओवरराइट कर रहा है।
  • तीसरी बार, यह तर्क के रूप में 3 के साथ ब्लॉक को इनबॉक्स करता है, और 9 वापस ले जाता है। फिर, यह blockReturnValue में मान को ओवरराइट करता है।
  • चौथा बार, हम blockReturnValue में स्टोर करते हैं।
  • पांचवां समय, हम 15blockReturnValue में स्टोर करते हैं।

फिर हम लूप के लिए बाहर निकलें, और 15 लौटें। तो हाँ, आप सही हैं कि आपने 3 से गुणा करने के लिए एक व्यर्थ विधि बनाई है। लेकिन आप इसे इस तरह से कर रहे हैं जो भी करता है बेकार गणना का गुच्छा।

+0

ठीक है। शायद यह आसान है कि मैं इसे बाहर कर रहा हूं। उस पर काम करना – baptzmoffire

+0

ठीक है। कृपया "और संपादित करें:" मदद के लिए धन्यवाद, बीजे। – baptzmoffire

+1

मुझे लगता है कि दुर्भाग्य से मेरे पास कम प्रोग्रामिंग IQ है। : पी मुझे क्या हो रहा है की जानकारी मिलती है। यह स्पष्ट होना चाहिए, लेकिन यह सिर्फ वाक्यविन्यास है जो मुझे फिट बैठता है, मुझे लगता है। यही कारण है कि मुझे वास्तव में क्या चल रहा है इसका पालन करने से रोक रहा है। मैं सिर्फ ब्लॉक के बारे में उतना ही खा रहा हूं जितना मैं कर सकता हूं जब तक कि मैं अंत में देखता हूं कि वे कैसे काम करते हैं और जब उचित रूप से उपयोग करते हैं। आपकी मदद और धैर्य के लिए बहुत बहुत धन्यवाद। – baptzmoffire

8

आपके प्रश्न को पढ़ने से मैं समझ गया, या शायद गलत समझा, कि आपका इरादा आपके ब्लॉक एन बार लागू करने के परिणाम उत्पन्न करना था; जैसे यदि आपने दो बार एक ट्रिपलिंग फ़ंक्शन लागू किया है तो आपको मूल मान नौ गुणा हो जाएगा।

@interface AnObject 

typedef int (^monadic)(int); // an function which takes an int and return an int 

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock; 

@end 

@implementation AnObject 

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock 
{ 
    for (int i = 0; i < howManyTimes; i++) 
     value = someBlock(value); 

    return value; 
} 

@end 

अब के साथ इस फोन:

AnObject *myObject = [AnObject new]; 

int z = [myObject repeat:5 
        for:1 
       withBlock: ^(int number) 
          { 
          return number * 3; 
          } 
     ]; 

और z मूल्य 243 होगा

बस के मामले में यह मदद करता है, यहाँ ऐसा करने के लिए कोड है।

+0

प्रतिक्रिया के लिए धन्यवाद, सीआरडी। आपको समय लेने की सराहना करते हैं। उपरोक्त "अद्यतन" देखें। – baptzmoffire

+0

@baptzmoffire - सही, ओह :-(टाइपो को ठीक किया गया है, अब यह 243 का उत्पादन करता है! – CRD

+0

धन्यवाद, सीआरडी। :) – baptzmoffire

1
@import Foundation; 

typedef int(^MyBlockType)(int); 

@implementation NSObject(extra) 
+ (int)invokeBlock:(MyBlockType)block withArgument:(int)arg 
{ 
    return block(arg); 
} 
@end; 

int main() { 
    @autoreleasepool { 
     NSLog(@"executeBlock(3) returns %d", 
       [NSObject invokeBlock:^(int param) { return param * param; } withArgument:3]); 
    } return 0; 
} 
संबंधित मुद्दे