दिलचस्प पोस्ट
SQL सर्वर: पहली पंक्ति में कैसे जुड़ें अधिसूचना पर क्लिक करने के बाद आवेदन खोलें कैसे बाइट सरणी को स्ट्रिंग में परिवर्तित करें कैसे एक PHP सरणी से एक HTML तालिका बनाने के लिए? उद्धरण चिह्नों के साथ बैज रेगेक्स? क्या इस मोड को खोजने के लिए एक अंतर्निहित कार्य है? रूबी: सरणी में एक डुप्लिकेट मान कैसे प्राप्त करें और वापस लौटें? एक जार के भीतर जेआर सहित कक्षापथ वर्तमान C या C ++ मानक दस्तावेज़ कहां से मिलते हैं? आर में लूप ऑपरेशन को गति दें उद्देश्य-सी में शून्य को संदेश भेजना मैं कैसे पता लगा सकता हूँ कि किस प्रक्रिया को .NET का उपयोग कर फ़ाइल लॉक कर रही है? कारखाना / डी को संयोजित नहीं किया जा सकता है कैसे एंड्रॉइड में एक्शनबार शीर्षक को संरेखित करें? MySQL की तरह ()?

क्या मैं उद्देश्य-सी ब्लॉक को गुणों के रूप में उपयोग कर सकता हूं?

क्या मानक गुण वाक्यविन्यास का उपयोग कर गुणों को ब्लॉक करना संभव है?

क्या एआरसी के लिए कोई बदलाव है?

वेब के समाधान से एकत्रित समाधान "क्या मैं उद्देश्य-सी ब्लॉक को गुणों के रूप में उपयोग कर सकता हूं?"

@property (nonatomic, copy) void (^simpleBlock)(void); @property (nonatomic, copy) BOOL (^blockWithParamter)(NSString *input); 

यदि आप कई स्थानों में उसी ब्लॉक को दोहराते हुए एक प्रकार डीएफ़ का इस्तेमाल करते हैं

 typedef void(^MyCompletionBlock)(BOOL success, NSError *error); @property (nonatomic) MyCompletionBlock completion; 

यहां इस बात का एक उदाहरण है कि आप ऐसा कार्य कैसे पूरा करेंगे:

 #import <Foundation/Foundation.h> typedef int (^IntBlock)(); @interface myobj : NSObject { IntBlock compare; } @property(readwrite, copy) IntBlock compare; @end @implementation myobj @synthesize compare; - (void)dealloc { // need to release the block since the property was declared copy. (for heap // allocated blocks this prevents a potential leak, for compiler-optimized // stack blocks it is a no-op) // Note that for ARC, this is unnecessary, as with all properties, the memory management is handled for you. [compare release]; [super dealloc]; } @end int main () { @autoreleasepool { myobj *ob = [[myobj alloc] init]; ob.compare = ^ { return rand(); }; NSLog(@"%i", ob.compare()); // if not ARC [ob release]; } return 0; } 

अब, केवल एक चीज है जिसे बदलने की आवश्यकता होगी यदि आपको तुलना के प्रकार को बदलने की जरूरत है तो typedef int (^IntBlock)() यदि आपको दो ऑब्जेक्ट्स को पास करने की आवश्यकता है, तो उसे इसे बदलें: typedef int (^IntBlock)(id, id) , और अपने ब्लॉक को इसमें बदलें:

 ^ (id obj1, id obj2) { return rand(); }; 

आशा है कि ये आपकी मदद करेगा।

12 मार्च 2012 को संपादित करें:

एआरसी के लिए, कोई विशेष परिवर्तन की आवश्यकता नहीं है, क्योंकि एआरसी आपके लिए ब्लॉक को तब तक प्रबंधित करेगा जब तक कि उन्हें प्रति के रूप में परिभाषित किया जाता है आपको संपत्ति को अपने नाशक में शून्य करने की आवश्यकता नहीं है, या तो

अधिक पढ़ने के लिए, कृपया इस दस्तावेज़ को देखें: http://clang.llvm.org/docs/AutomaticReferenceCounting.html

स्विफ्ट के लिए, बस क्लोजर का उपयोग करें: उदाहरण।


उद्देश्य-सी में,

@प्रॉपर्टी (कॉपी) शून्य (^ डस्टफुट) (शून्य);

यह इत्ना आसान है।

एप्पल के प्रलेखन, इस मुद्दे को पूरी तरह समझाते हुए:

ऐप्पल डॉको

आपके .h फाइल में:

 // Here is a block as a property: // // Someone passes you a block. You "hold on to it", // while you do other stuff. Later, you use the block. // // The property 'doStuff' will hold the incoming block. @property (copy)void (^doStuff)(void); // Here's a method in your class. // When someone CALLS this method, they PASS IN a block of code, // which they want to be performed after the method is finished. -(void)doSomethingAndThenDoThis:(void(^)(void))pleaseDoMeLater; // We will hold on to that block of code in "doStuff". 

यहां आपके। मी फ़ाइल है:

  -(void)doSomethingAndThenDoThis:(void(^)(void))pleaseDoMeLater { // Regarding the incoming block of code, save it for later: self.doStuff = pleaseDoMeLater; // Now do other processing, which could follow various paths, // involve delays, and so on. Then after everything: [self _alldone]; } -(void)_alldone { NSLog(@"Processing finished, running the completion block."); // Here's how to run the block: if ( self.doStuff != nil ) self.doStuff(); } 

आउट-टू-डेट उदाहरण कोड से सावधान रहें

आधुनिक (2014+) प्रणालियों के साथ, यहां दिखाए गए कार्य करें। यह आसान है आशा है कि यह किसी को मदद करता है मेरी क्रिसमस 2013!

भावी पीढ़ी / पूर्णता के लिए … यहां दो पूर्ण उदाहरण दिए गए हैं कि इस हास्यास्पद बहुमुखी "काम करने का तरीका" कैसे कार्यान्वित करें। @ रॉबर्ट का उत्तर बिलकुल संक्षिप्त और सही है, लेकिन यहां मैं वास्तव में ब्लॉकों को परिभाषित करने के तरीकों को भी दिखाना चाहता हूं।

 @interface ReusableClass : NSObject @property (nonatomic,copy) CALayer*(^layerFromArray)(NSArray*); @end @implementation ResusableClass static NSString const * privateScope = @"Touch my monkey."; - (CALayer*(^)(NSArray*)) layerFromArray { return ^CALayer*(NSArray* array){ CALayer *returnLayer = CALayer.layer for (id thing in array) { [returnLayer doSomethingCrazy]; [returnLayer setValue:privateScope forKey:@"anticsAndShenanigans"]; } return list; }; } @end 

बेवकूफ? हाँ। उपयोगी? बरबाद हाँ। यहां संपत्ति सेट करने का एक अलग, "अधिक परमाणु" तरीका है .. और एक वर्ग जो हास्यास्पद रूप से उपयोगी है …

 @interface CALayoutDelegator : NSObject @property (nonatomic,strong) void(^layoutBlock)(CALayer*); @end @implementation CALayoutDelegator - (id) init { return self = super.init ? [self setLayoutBlock: ^(CALayer*layer){ for (CALayer* sub in layer.sublayers) [sub someDefaultLayoutRoutine]; }], self : nil; } - (void) layoutSublayersOfLayer:(CALayer*)layer { self.layoutBlock ? self.layoutBlock(layer) : nil; } @end 

यह एक्सेसर के माध्यम से ब्लॉक प्रॉपर्टी को सेट करने की व्याख्या करता है (यद्यपि इनट के अंदर, डेबेटली डिसी प्रैक्टिस ..) पहले उदाहरण के "नॉनैटोमिक" "गायटर" तंत्र से बना है। या तो मामले में … "हार्डकोड" कार्यान्वयन हमेशा ओवरराइट किया जा सकता है, उदाहरण के लिए .. एक ला ..

 CALayoutDelegator *littleHelper = CALayoutDelegator.new; littleHelper.layoutBlock = ^(CALayer*layer){ [layer.sublayers do:^(id sub){ [sub somethingElseEntirely]; }]; }; someLayer.layoutManager = littleHelper; 

इसके अलावा .. अगर आप किसी श्रेणी में एक ब्लॉक संपत्ति जोड़ना चाहते हैं … कहते हैं कि आप कुछ पुराने-स्कूल लक्ष्य / क्रिया "एक्शन" के बजाय एक ब्लॉक का उपयोग करना चाहते हैं … आप केवल संबद्ध मानों का उपयोग, ठीक से कर सकते हैं .. ब्लॉकों को संबद्ध करें

 typedef void(^NSControlActionBlock)(NSControl*); @interface NSControl (ActionBlocks) @property (copy) NSControlActionBlock actionBlock; @end @implementation NSControl (ActionBlocks) - (NSControlActionBlock) actionBlock { // use the "getter" method's selector to store/retrieve the block! return objc_getAssociatedObject(self, _cmd); } - (void) setActionBlock:(NSControlActionBlock)ab { objc_setAssociatedObject( // save (copy) the block associatively, as categories can't synthesize Ivars. self, @selector(actionBlock),ab ,OBJC_ASSOCIATION_COPY); self.target = self; // set self as target (where you call the block) self.action = @selector(doItYourself); // this is where it's called. } - (void) doItYourself { if (self.actionBlock && self.target == self) self.actionBlock(self); } @end 

अब, जब आप एक बटन बनाते हैं, तो आपको कुछ IBAction ड्रामा सेट अप करने की ज़रूरत नहीं है .. बस सृजन पर काम करने के लिए संबद्ध करें …

 _button.actionBlock = ^(NSControl*thisButton){ [doc open]; [thisButton setEnabled:NO]; }; 

यह पैटर्न कोकोआ एपीआई के ऊपर और ऊपर लागू किया जा सकता है। अपने कोड के प्रासंगिक हिस्सों को एक साथ मिलाने के लिए गुणों का उपयोग करें, जटिल प्रतिनिधिमंडल के मानदंडों को समाप्त करें, और वस्तुओं की शक्ति को सिर्फ गूंगा "कंटेनर" के रूप में कार्य करने से परे का लाभ उठाएं।

बेशक आप ब्लॉक के गुणों के रूप में उपयोग कर सकते हैं लेकिन सुनिश्चित करें कि उन्हें @ प्रॉपर्टी (प्रतिलिपि) के रूप में घोषित किया गया है उदाहरण के लिए:

 typedef void(^TestBlock)(void); @interface SecondViewController : UIViewController @property (nonatomic, copy) TestBlock block; @end 

एमआरसी में, संदर्भ चर को पकड़ने वाले ब्लॉक को स्टैक में आवंटित किया जाता है; स्टैक फ्रेम नष्ट हो जाने पर वे रिहा हो जाएंगे। यदि वे प्रतिलिपि किए गए हैं, तो एक नए ब्लॉक को ढेर में आवंटित किया जाएगा, जिसे स्टैक फ्रेम पॉपड होने के बाद बाद में निष्पादित किया जा सकता है।

Disclamer

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

हैलो, स्विफ्ट

स्विफ्ट में काम करने के लिए आपके पास बराबर ब्लॉक पास करने की पेशकश करने के कई तरीके हैं।

मुझे तीन मिले

इसे समझने के लिए मैं आपको खेल के मैदान में इस छोटे से कोड का परीक्षण करने का सुझाव देता हूं।

 func test(function:String -> String) -> String { return function("test") } func funcStyle(s:String) -> String { return "FUNC__" + s + "__FUNC" } let resultFunc = test(funcStyle) let blockStyle:(String) -> String = {s in return "BLOCK__" + s + "__BLOCK"} let resultBlock = test(blockStyle) let resultAnon = test({(s:String) -> String in return "ANON_" + s + "__ANON" }) println(resultFunc) println(resultBlock) println(resultAnon) 

स्विफ्ट, क्लोजर के लिए अनुकूलित

जैसा कि स्विफ्ट एसिंक्रोनस डेवलपमेंट के लिए अनुकूलित है, ऐप्पल ने क्लोजर पर अधिक काम किया। पहला यह है कि फ़ंक्शन के हस्ताक्षर का अनुमान लगाया जा सकता है, इसलिए आपको इसे फिर से लिखना नहीं है।

संख्याओं के आधार पर पैरामीटर का उपयोग करें

 let resultShortAnon = test({return "ANON_" + $0 + "__ANON" }) 

नामकरण के साथ परम अनुमान

 let resultShortAnon2 = test({myParam in return "ANON_" + myParam + "__ANON" }) 

ट्रेलिंग क्लोजर

यह विशेष मामला तभी काम करता है जब ब्लॉक अंतिम तर्क होता है, इसे समापन समापन कहा जाता है

यहां एक उदाहरण है (स्विफ्ट पावर दिखाने के लिए अनुमानित हस्ताक्षर के साथ विलय)

 let resultTrailingClosure = test { return "TRAILCLOS_" + $0 + "__TRAILCLOS" } 

आखिरकार:

यह सब शक्ति का उपयोग करना जो मैं करता हूँ, उसका समापन और प्रकार अनुमान (पठनीयता के लिए नामकरण के साथ) का मिश्रण होता है

 PFFacebookUtils.logInWithPermissions(permissions) { user, error in if (!user) { println("Uh oh. The user cancelled the Facebook login.") } else if (user.isNew) { println("User signed up and logged in through Facebook!") } else { println("User logged in through Facebook!") } } 

हैलो, स्विफ्ट

पूरक क्या @ Francescu उत्तर दिया

अतिरिक्त पैरामीटर जोड़ना:

 func test(function:String -> String, param1:String, param2:String) -> String { return function("test"+param1 + param2) } func funcStyle(s:String) -> String { return "FUNC__" + s + "__FUNC" } let resultFunc = test(funcStyle, "parameter 1", "parameter 2") let blockStyle:(String) -> String = {s in return "BLOCK__" + s + "__BLOCK"} let resultBlock = test(blockStyle, "parameter 1", "parameter 2") let resultAnon = test({(s:String) -> String in return "ANON_" + s + "__ANON" }, "parameter 1", "parameter 2") println(resultFunc) println(resultBlock) println(resultAnon) 

आप नीचे प्रारूप का अनुसरण कर सकते हैं और क्लास में testingObjectiveCBlock प्रॉपर्टी का उपयोग कर सकते हैं।

 typedef void (^testingObjectiveCBlock)(NSString *errorMsg); @interface MyClass : NSObject @property (nonatomic, strong) testingObjectiveCBlock testingObjectiveCBlock; @end 

अधिक जानकारी के लिए यहां देखें