Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Objective-C blocks as properties?

Is it possible to have blocks as properties using the standard property syntax?

Are there any changes for ARC?

like image 530
gurghet Avatar asked Oct 14 '10 16:10

gurghet


People also ask

What are Objective-C properties?

The Objective-C declared properties feature provides a simple way to declare and implement an object's accessor methods.

What is the purpose of block in Objective-C?

Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary .

What is copy property?

"The copy attribute is an alternative to strong. Instead of taking ownership of the existing object, it creates a copy of whatever you assign to the property, then takes ownership of that. Only objects that conform to the NSCopying protocol can use this attribute..."


2 Answers

@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; 
like image 53
Robert Avatar answered Sep 29 '22 22:09

Robert


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]; } @end  int 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

like image 23
Richard J. Ross III Avatar answered Sep 29 '22 22:09

Richard J. Ross III