Search code examples
iosobjective-c-blocksblock

Having issue understanding part of blocks


I am trying to wrap my head around block programming, and currently stuck in this problem

char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
    char *left = *(char **)l;
    char *right = *(char **)r;
    return strncmp(left, right, 1); 
});

On second line the block parameter ^(const void *l, const void *r), from where it is getting its parameter values.

From the Apple Block Programming Topics documentation:

Blocks with Cocoa

Several methods in the Cocoa frameworks take a block as an argument, typically either to perform an operation on a collection of objects, or to use as a callback after an operation has finished. The following example shows how to use a block with the NSArray method sortedArrayUsingComparator:. The method takes a single argument—the block. For illustration, in this case the block is defined as an NSComparator local variable:

What is the meaning of "in this case the block is defined as an NSComparator local variable"?

This is the code sample provided

NSArray *stringsArray = @[ @"string 1",
                         @"String 21",
                         @"string 12",
                         @"String 11",
                         @"String 02" ];
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch |
                                                  NSNumericSearch |
                                                  NSWidthInsensitiveSearch |
                                                  NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale];
NSComparator finderSortBlock = ^(id string1, id string2) {
    NSRange string1Range = NSMakeRange(0, [string1 length]);
    return [string1 compare:string2 
                    options:comparisonOptions 
                      range:string1Range
                     locale:currentLocale];
};
NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];     
NSLog(@"finderSortArray: %@", finderSortArray);

Where is ^(id string1, id string2) getting its parameter values?


Solution

  • NSComparator is actually a block typecasted as follows, typedef NSComparisonResult (^NSComparator)(id obj1, id obj2); same way as typedef double NSTimeInterval; or typedef long NSInteger;. Since it is a block, the format is slightly different with arguments. Basically NSComparator is a block which accepts two params obj1 and obj2 and returns an NSComparisonResult value to denote the ordering of the two objects. It can return NSOrderedAscending, NSOrderedSame or NSOrderedDescending. This can be used by sortedArrayUsingComparator to repeatedly compare two objects in array and sort it based on that. This also helps in implementing our own implementation for sorting. When the sorting happens this block is called by sortedArrayUsingComparator and gives values to obj1 and obj2 and executes the NSComparator block. From that block it returns NSComparisonResult based on the comparison we implemented.