2

Is it possible to pass a block of code, for example:

int i = 0;
while (i < [array count]) {

//Code to pass in here
i++;
}

Reason being that i need to perform various actions on every item in an array at different times, it'd be nice to have 1 method and pass it a block of code to run.

Andrew
  • 15,935
  • 28
  • 121
  • 203
  • 1
    Block of code? You mean run a method? – Trevor Jul 08 '11 at 12:56
  • do you mean to reflect UI in every loop control executes? – jigneshbrahmkhatri Jul 08 '11 at 12:57
  • 1
    +1 This isn't a bad question, just a misguided mindset. @Andrew, you should really be thinking in terms of abstraction and reusable methods instead of attempting to circumvent proper conventions by passing around code in your application. If you're simply attempting to resuse your loop, there are many ways to accomplish this without physically sending a block of code throughout your application. – George Johnston Jul 08 '11 at 12:59
  • @Trevor Run a method, but without having to create a method especially for it. – Andrew Jul 08 '11 at 12:59
  • Actually, there are many uses of code blocks, which is why they were added in Snow Leopard. – Perception Jul 08 '11 at 13:02
  • @Andrew, more code isn't a bad thing -- especially if it makes your application more readable and maintainable. – George Johnston Jul 08 '11 at 13:03
  • 1
    @Andrew I'm still a little bit confused on what you are trying to accomplish. – Trevor Jul 08 '11 at 13:06

9 Answers9

7

Have you considered using blocks. It's just an idea and not working or compilable code

typedef int (^block_t)();

-(void) methodName:(block_t) code_block
{  
   int i = 0;
   while (i < [array count]) {
   code_block() //Code to pass in here

   i++;
}

block_t youCode = ^{ NSLog("Just an example"); }
[self methodName:youCode];
Dmytro
  • 2,522
  • 5
  • 27
  • 36
4

You can definitely iterate an array and process a block of code on it. This feature has been a standard part of Objective C since 2.0, iOS since 4.0 and in addition was included in Snow Leopard. If you look up the NSArray class reference you will find the following functions:

enumerateObjectsAtIndexes:options:usingBlock: Executes a given block using the objects in the array at the specified indexes.

enumerateObjectsUsingBlock: Executes a given block using each object in the array, starting with the first object and continuing through the array to the last object.

enumerateObjectsWithOptions:usingBlock: Executes a given block using each object in the array.

You can define the code block to be executed globally in your implementation file, or in place where its needed. You can find some good examples on block programming here: http://thirdcog.eu/pwcblocks/.

Perception
  • 79,279
  • 19
  • 185
  • 195
  • And I also said they have been available since Objective C 2.0. I don't see the harm in including extra information that might be useful to other readers, but will edit to include iOS 4. – Perception Jul 08 '11 at 18:48
2

It sounds like you want "blocks", which are a feature of Objective-C similar to "lambdas", "anonymous functions" and "closures" in other languages.

See Apple's documentation: Blocks Programming Topics

Kristopher Johnson
  • 81,409
  • 55
  • 245
  • 302
1

You should put the code into a method and call the method like so:

-(void)foo{
    int i = 0;
    while (i < [array count]) {
        [self myMethod];
        i++;
    }
}
-(void)myMethod{
     //Code to pass in here
}

You could also store the method as a variable allowing you to change which method is called

SEL methodToCall = @selector(myMethod);

-(void)foo{
    int i = 0;
    while (i < [array count]){
        [self performSelector:methodToCall];
        i++;
    }
}
-(void)myMethod{
     //Code to pass in here
}
eazimmerman
  • 599
  • 4
  • 20
0

If you are using Objective C++, I would strongly recommend function objects (even over blocks). They have a nice syntax, are easy to use, and are supported everywhere on modern C++ compilers (MSVC++11, GNUC++11, and LLVMC++11):

void go( function<void (int arg)> func )
{
  int i = 0;
  while (i < [array count]) {

    //Code to pass in here
    func( i ) ; // runs func on i
    i++;
  }
}

calling it:

go( []( int arg ){ // the square brackets are the "capture"
  printf( "arg was %d\n", arg ) ; // arg takes on whatever value was passed to it,
  // just like a normal C function
} ) ;
bobobobo
  • 64,917
  • 62
  • 258
  • 363
0

Why not just define functions that do what you want, and call them at various times with the items in your array as arguments?

If your concern is that you don't want redundant code with multiple while loops you have here, you could write a function that takes an array and a function as an argument, then applies that function to every element in the array.

Adapted from here:

//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer

// <pt2Func> is a pointer to a function which returns void and takes an NSObject*
void DoForAllItems( NSArray* array, void (*pt2Func)(NSObject*) )
{
    int i = 0;
    while (i < [array count]) {

        (*pt2Func)([array objectAtIndex:i]);
        i++;
    }
}

// 'DoIt' takes an NSObject*
void DoIt (NSObject* object){ NSLog(@"DoIt"); }

// execute example code
void Pass_A_Function_Pointer()
{
   NSArray* array= [NSArray arrayWithObjects:@"1", @"2", nil];
   DoForAllItems(array, &DoIt);
}
Luke
  • 7,110
  • 6
  • 45
  • 74
  • 'you could write a function that takes an array and a function as an argument, then applies that function to every element in the array.' this is exactly what i wish to do. how do i do this? – Andrew Jul 08 '11 at 13:08
  • See my edit - this is how you can pass a function as an argument. – Luke Jul 08 '11 at 13:21
0

first of all you could give a more detailed example. second you could take a look at Action or Func in case you need a return message (well something equivalent for obj-C if exists)

but again, not understanding what you need to do, it is hard to give you an answer

cause from you Q i could understand as @Trevor did that you need to run a method:

int i = 0;
while (i < [array count]) {

   if (i % 2) 
       EvenMethod(array[i])
   else
       OddMethod(array[i])

i++;
}
undertakeror
  • 1,022
  • 7
  • 11
0

If you can live with 4.0+ compatibility, I highly recommend the use of blocks.

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

gives you all you need and you can define your block right where you need it. There are some other variants of this, too. Please refer to the 'NSArray' documentation.

Eiko
  • 25,601
  • 15
  • 56
  • 71
0

http://thirdcog.eu/pwcblocks/#objcblocks

Blocks were added recently to Objective-C I hope they have found their way to the Iphone also. and it was anwered here also before: Using Objective-C Blocks

Regards

Community
  • 1
  • 1
Friedrich
  • 5,916
  • 25
  • 45