Objective-C: typedef'd a block, used it in a method declaration. How do I implement this?

block, objective-c

Solution

Just call the block like a regular C function.

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock {
    for (int i = 0; i <= howManyTimes; i++) {
        int blockReturnValue = someBlock(i);
        // do something with blockReturnValue
    }
}

Update after your "further edit"

No, the block you passed in as an argument is run five times, each pass through the for loop.

- The first time, it invokes the block with `1` as the argument, and gets back `3`. It stores that in `blockReturnValue`, then goes on to the next iteration of the loop.

- The second time, it invokes the block with `2` as the argument, and gets back `6`. It stores that in `blockReturnValue`, completely overwriting the value we stored there in the previous pass.

- The third time, it inbokes the block with `3` as the argument, and gets back `9`. Again, it overwrites the value in `blockReturnValue`.

- The fourth time, we store `12` in `blockReturnValue`.

- The fifth time, we store `15` in `blockReturnValue`.

Then we exit the for loop, and return 15. So yes, you're correct that you've made a pointless method to multiply by 3. But you're doing it in a way that also does a bunch of useless calculations.

Problem

Just trying to get a handle on blocks. I get the concept. They're like function pointers, but they're actually objects; you can declare a block variable and assign it a block value; call it like a function; they get "frozen in time," for lack of a term, when they get executed, etc. I've created a few blocks and run them successfully, in a few different formats, but when it comes to using them in a method--either with a typedef or without--I'm having a lot of trouble. For example, here's an object interface I created, just to get a handle on the syntax. I have almost no idea how to implement it. ``` // AnObject.h #import <Foundation/Foundation.h> // The idea with the block and the method below is for the block to take // an int, multiply it by 3, and return a "tripled" int. The method // will then repeat: this process however many times the user wants via // the howManyTimes parameter and return that value in the form of an int. typedef int (^triple)(int); @interface AnObject : NSObject { int num; } -(int)repeat:(int)howManyTimes withBlock:(triple)someBlock; @end ``` Here's what I have for an implementation, so far: ``` #import "AnObject.h" @implementation AnObject @synthesize num; -(int)repeat:(int)howManyTimes withBlock:(triple)someBlock { for (int i = 0; i <= howManyTimes; i++) { // What the heck am I supposed to put here? I'm baffled by the // syntax over and over again. } } @end ``` I know I'm not addressing the instance variable yet. Again, this is a rough draft, just trying to get a handle on how blocks work. Am I even declaring this method right? I'm reading Big Nerd Ranch's Objective-C Programming, Mike Clark's article on blocks from Pragmatic Studio, and several SO threads. Can't find anything relevant. Thanks. EDIT: XCode 4.3.2, if it matters. FURTHER EDIT: Ok. Using BJ's (slightly modified) example, I think I've come up with a really complicated way of multiplying 5 by 3. :) ``` // BJ's implementation: -(int)repeat:(int)howManyTimes withBlock:(Triple)someBlock { int blockReturnValue; for (int i = 0; i <= howManyTimes; i++) { blockReturnValue = someBlock(i); } return blockReturnValue; } ``` Main: ``` ... @autoreleasepool { AnObject *obj = [[AnObject alloc] init]; NSLog(@"%d", [obj repeat: 5 withBlock: ^ (int number) { return number * 3; }]); } return 0; ... ``` And the output is: ``` 15 ``` Now, it's kicking back 15, because the block I defined as an argument is run only once, right? It multiplies "number," which is 5 in this case, by 3 and freezes that answer, right? I'm sure I just created a completely useless method, and I don't yet understand how to utilize the benefits/features of a block. Am I correct? /********************* UPDATE *********************/ UPDATE: I understand what you're saying, CRD. Just a correction though, for any new programmers who might be reading this, getting a different output and going, "Que?" Your for loop should be either: ``` for (int i = 0; i < howManyTimes; i++) value = someBlock(value); ``` ...or... ``` (i = 1; i <= howManyTimes; i++) ``` ...to get the answer 243. And, yes, this is exactly what I was initially trying to do with this code. At least that's what I thought was supposed to be happening. Turns out the author's intent wasn't to triple a number, store that value, triple the stored value, store that...etc., but rather just to print x * 3 for numbers 1-5 (3, 6, 9, 12, 15). Here is the finished product. I just typedef'd a block that takes an int and returns an int, called Tripler. I also changed the name of the argument from "someBlock" to "triple" to more clearly indicate the intended use of the block. I think those are the only changes to the code. ``` /******************** interface ********************/ #import <Foundation/Foundation.h> typedef int (^Tripler)(int); @interface AnObject : NSObject -(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple; @end /******************** implementation ********************/ #import "AnObject.h" @implementation AnObject -(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple { for (int i = 1; i <= number; i++) { NSLog(@"%d", triple(i)); } } @end /******************** main.m ********************/ #import "AnObject.h" #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { AnObject *obj = [[AnObject alloc] init]; [obj iterateFromOneTo:5 withBlock:^(int number) { return number * 3; }]; } return 0; } ``` As you can probably imagine, the resulting output is: ``` 2012-05-05 17:10:13.418 Untitled 2[71735:707] 3 2012-05-05 17:10:13.445 Untitled 2[71735:707] 6 2012-05-05 17:10:13.446 Untitled 2[71735:707] 9 2012-05-05 17:10:13.446 Untitled 2[71735:707] 12 2012-05-05 17:10:13.447 Untitled 2[71735:707] 15 ``` I was making it a lot more complicated than it needed to be. Sorry for explaining it so poorly in the OP. Thanks for your help! /thread? :)

Original source