72

I would like to write a method similar to this:

+(void)myMethodWithView:(UIView *)exampleView completion:(void (^)(BOOL finished))completion;

I've basically stripped down the syntax taken from one of Apple's class methods for UIView:

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

And would expect it to be used like so:

[myFoo myMethodWithView:self.view completion:^(BOOL finished){
                     NSLog(@"call back success");
                 }];

My question is how can I implement this? If someone can point me to the correct documentation that would be great, and a very basic example would be much appreciated (or a similar answer on Stack Overflow -- I couldn't find one). I still don't quite know enough about delegates to determine whether that is even the correct approach!

I've put a rough example of what I would have expected it to be in the implementation file, but as I can't find info it's guess work.

+ (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion {
    // do stuff

    if (completion) {
        // what sort of syntax goes here? If I've constructed this correctly!
    }

}
Chris
  • 2,478
  • 3
  • 23
  • 38
  • I wonder why no one has mentioned the fact that the `finished` in the parameter type is quite unnecessary in this example... – funct7 Jan 03 '17 at 09:12

3 Answers3

85

You can call a block like a regular function:

BOOL finished = ...;
if (completion) {
    completion(finished);
}

So that means implementing a complete block function using your example would look like this:

+ (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion {
    if (completion) {
        completion(finished);
    }
}
whitneyland
  • 10,632
  • 9
  • 60
  • 68
omz
  • 53,243
  • 5
  • 129
  • 141
  • That was painfully straight forward, many thanks! Site says it's too early to accept the answer, I will do once I'm back on the computer – Chris Aug 24 '11 at 18:48
  • Also take a note that in your example you create block on stack, so there is possibility that block will die before it is executed. To avoid this, make [[completion copy] autorelease] in your method, that accepts block. – Timur Kuchkarov Feb 19 '13 at 03:44
  • @TimurKuchkarov - can you past some code so I can see where the [completion copy] should go in the method? All a little confusing to my simple mind :) – So Over It Apr 19 '13 at 05:07
  • 1
    "Typically, you shouldn’t need to copy (or retain) a block. You only need to make a copy when you expect the block to be used after destruction of the scope within which it was declared. Copying moves a block to the heap.". Also a good link is - http://www.mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html . As for me, I'm generally copying at the start of method where block is passed. – Timur Kuchkarov May 22 '13 at 06:53
  • when i copypaste + (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion { if (completion) { completion(finished); } } – alex440 Oct 30 '13 at 08:36
  • sorry but ı can't understand this answer? what is completion ? it's typdef ? can you add a tutorial ? thnak you – Erhan Demirci Dec 01 '13 at 07:02
  • 1
    @ErhanDemirci the `completion` is the actual block. It is defined in the method signature. (void (^)(BOOL finished))completion allows invoking a completion() method that is used as a call back. Check out apples docs: https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html – Johnathon Sullinger Jan 26 '14 at 23:17
  • Thank you @jonhathon . how method can method understand mission is finished ? – Erhan Demirci Jan 27 '14 at 07:46
5

I would highly recommend that you read up on Blocks to understand what is happening.

Chaitanya Gupta
  • 4,043
  • 2
  • 31
  • 41
  • when I copypaste + (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion { if (completion) { completion(finished); } } I get "use of undeclared identifier finished".... – alex440 Oct 30 '13 at 08:36
1

If you're specially looking for a doc, to create custom method using blocks, then the following link is the one which explains almost everything about it. :)

http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/Blocks/Articles/bxUsing.html

I happen to answer quite a same question recently, have a look at this: Declare a block method parameter without using a typedef

Community
  • 1
  • 1