Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For posterity / completeness's sake… Here are two FULL examples of how to implement this ridiculously versatile "way of doing things". @Robert's answer is blissfully concise and correct, but here I want to also show ways to actually "define" the blocks. </p> <pre><code>@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 </code></pre> <p>Silly? <em>Yes.</em> Useful? <strong><em>Hells yeah.</em></strong> Here is a different, "more atomic" way of setting the property.. and a class that is ridiculously useful…</p> <pre><code>@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 </code></pre> <p>This illustrates setting the block property via the accessor (albeit inside init, a debatably dicey practice..) vs the first example's "nonatomic" "getter" mechanism. In either case… the "hardcoded" implementations can always be overwritten, <em>per instance</em>.. a lá..</p> <pre><code>CALayoutDelegator *littleHelper = CALayoutDelegator.new; littleHelper.layoutBlock = ^(CALayer*layer){ [layer.sublayers do:^(id sub){ [sub somethingElseEntirely]; }]; }; someLayer.layoutManager = littleHelper; </code></pre> <p>Also.. if you want to add a block property in a category... say you want to use a Block instead of some old-school target / action "action"... You can just use associated values to, well.. associate the blocks.</p> <pre><code>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 &amp;&amp; self.target == self) self.actionBlock(self); } @end </code></pre> <p>Now, when you make a button, you don't have to set up some <code>IBAction</code> drama.. Just associate the work to be done at creation... </p> <pre><code>_button.actionBlock = ^(NSControl*thisButton){ [doc open]; [thisButton setEnabled:NO]; }; </code></pre> <p>This pattern can be applied <em>OVER and OVER to</em> Cocoa API's. Use properties to bring the relevant parts of your code <em>closer together</em>, eliminate <em>convoluted delegation paradigms</em>, and leverage the power of objects beyond that of just acting as dumb "containers".</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload