Can I use Objective-C blocks as properties? Can I use Objective-C blocks as properties? ios ios

Can I use Objective-C blocks as properties?


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

If you are going to be repeating the same block in several places use a type def

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


Here's an example of how you would accomplish such a task:

#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];}@endint main () {    @autoreleasepool {        myobj *ob = [[myobj alloc] init];        ob.compare = ^        {            return rand();        };        NSLog(@"%i", ob.compare());        // if not ARC        [ob release];    }    return 0;}

Now, the only thing that would need to change if you needed to change the type of compare would be the typedef int (^IntBlock)(). If you need to pass two objects to it, change it to this: typedef int (^IntBlock)(id, id), and change your block to:

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

I hope this helps.

EDIT March 12, 2012:

For ARC, there are no specific changes required, as ARC will manage the blocks for you as long as they are defined as copy. You do not need to set the property to nil in your destructor, either.

For more reading, please check out this document:http://clang.llvm.org/docs/AutomaticReferenceCounting.html


For Swift, just use closures: example.


In Objective-C:

@property (copy)void

@property (copy)void (^doStuff)(void);

It's that simple.

Here is the actual Apple documentation, which states precisely what to use:

Apple doco.

In your .h file:

// 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".

Here's your .m file:

 -(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();    }

Beware of out-of-date example code.

With modern (2014+) systems, do what is shown here. It is that simple.