What is the '^' in Objective-C

Discussion in 'Mac Programming' started by zzyplza, Apr 29, 2010.

  1. zzyplza macrumors newbie

    Joined:
    Apr 29, 2010
    #1
    I'm stuck. What does the '^' mean in the code below?
    ===
    Code:
    @implementation AppController
    
    - (IBAction) loadComposition:(id)sender
    {
        void (^handler)(NSInteger);
    	
        NSOpenPanel *panel = [NSOpenPanel openPanel];
    	
        [panel setAllowedFileTypes:[NSArray arrayWithObjects: @"qtz", nil]];
    	
        handler = ^(NSInteger result) {
            if (result == NSFileHandlingPanelOKButton) {
                NSString *filePath = [[[panel URLs] objectAtIndex:0] path];
                if (![qcView loadCompositionFromFile:filePath]) {
                    NSLog(@"Could not load composition");
                }
            }
        };
    	
        [panel beginSheetModalForWindow:qcWindow completionHandler:handler];
    }
    @end
    ===
    It's not XOR of course..

    Thanks.
     
  2. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #2
    They're blocks, an extension for C Apple introduced in 10.6. In this case it's basically a function that runs once the save panel has finished with the result of the save panel. They also have read only access to all the local variables of the current method.

    For more information see:
    http://developer.apple.com/mac/articles/cocoa/introblocksgcd.html
     
  3. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #3
    Go to www.developer.com and enter "blocks" into the search box. Then start reading. And it is available in C, C++, Objective-C and Objective-C++ from 10.6 onwards.
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    Not that this was what you were asking, but it's also the binary bitwise-xor. This is used as:
    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv) {
      int x,y,z;
      char res[33];
      int pos = 0;
      //  b'0110 0100 1010 0100 0100 1011 1100 0100';
      x = 0x64A44BC8;
      //  b'1010 0000 1111 0110 0111 0011 1001 0100';
      y = 0xA0F67398;
      z = x ^ y;
      printf("The hex is: %x\n",z);
      for(pos = 0; pos < 32; pos++) {
        if(((1<<pos) & z) != 0) {
          res[31-pos] = '1';
        } else {
          res[31-pos] = '0';
        }
      }
      res[32] = '\0';
      printf("The result is: %s\n",res);
    }
    
    Obviously the ^(block) syntax is different than x^y, but i figure it's nice to know all of the things an operator might do.

    -Lee

    EDIT: Looks like you mentioned XOR in your original post. Oh well, no use in taking this down now.
     
  5. Thomas Harte macrumors 6502

    Joined:
    Nov 30, 2005
    #5
    More than that, they're full closures aren't they? So you get read only access to the local variables, but they retain the values they had when the block was declared. It doesn't matter if the variables change value afterwards, meaning that e.g. blocks do what you'd want them to do if the declaration is part of a loop.
     
  6. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #6
    You can get write access to locals of the enclosing function by declaring them __block:

    Code:
    int main() {
        __block int x = 5;
        void (^demo)() = void (^demo)() {
            x = 10;
        };
        demo();
        printf("%d", x); //prints 10
    }
    
    This is very important for replacing mutexes with libdispatch:

    Code:
    - (void) setFoo:(id)newFoo {
        dispatch_sync(lockQueue, ^{
            if (foo != newFoo) {
                [foo release];
                foo = [newFoo copy];
            }
        });
    }
    
    - (id) foo {
        __block id result = nil;
        dispatch_sync(lockQueue, ^{
            result = [foo copy];
        });
        return [result autorelease];
    }
    
     

Share This Page