How to use Blocks with iOS

來源:互聯網
上載者:User
Blocks are what help organise your code into independent snippets of code, optimised for re-use and readability. They have been introduced into our UIKit world in iOS 4, along with over 100
Apple APIs that make use of blocks, so it is something that you should start getting used to.

What do Blocks look like?

You use the ^ caret operator to signify a block variable, indicative of the beginning of the block.

int num1 = 7;int(^aBlock)(int) = ^(int num2) {   return num1+nunm2;};

Looking at the code above, we declared the block as a variable, so we can utilise it as a function:

NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56.

We just saw how to use blocks as variables, but in most cases we use the block literals inline, such as in an argument. The APIs either normally use blocks to perform an operation on a collection of objects, or as a callback after an operation has finished.

NSComperator compareStringsBlock = ^(id stringA, id stringB) {NSRange rangeS  = NSMakeRange (0, [stringA length]);return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale];};NSArray *compareSortArray  = [arrayOfStringDays sortArrayUsingComparator: compareStringsBlock]);

Blocks provide the advantage of creating ad-hoc function body as an expression. Apple Documentation states that:

A block is an anonymous inline collection of code that:

• Has a typed argument list just like a function

• Has an inferred or declared return type

• Can capture state from the lexical scope within which it is defined

• Can optionally modify the state of the lexical scope

• Can share the potential for modification with other blocks defined within the same lexical scope

• Can continue to share and modify state defined within the lexical scope (the stack frame) after the lexical scope (the stack frame) has been destroyed

Blocks are small self-contained snippets that encapsulate units of work that may be executed
concurrently, over items (line enumeration) or as
callbacks.

Declaring and Using Blocks

Apple show us in their documentation how we declare a block as a variable, using it as a function

int (^oneFrom)(int) = ^(int anInt) {    return anInt - 1;};//We create an inline block literal ^(int anInt)... with the body and the result gets passed to another block OneFrom.printf("1 from 10 is %d", oneFrom(10));// Prints "1 from 10 is 9" //This block function (distanceTraveled) gets three float arguments, returning float. float (^distanceTraveled) (float, float, float) =                          ^(float startingSpeed, float acceleration, float time) {     float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);    return distance;}; 

You can also pass a block as an argument and instead of declaring them (like we did above) you can simply implement the code inline, where they are required as an argument:

NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil]; sortFunction(anArray, ^(string *a string *b){if ( a == @"cat") return TRUE; }); 

So we can see we have an inline block snippet take the place of the last argument (has to be the last argument in the list of arguments ). Cocoa provides number of methods that use blocks, so you pass a block as a method argument:

NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];

NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil]; BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL//body of block gets the block literal ^(id obj, NSUInteger idx, Bool *stop)... and the body logic test = ^ (id obj, NSUInteger idx, BOOL *stop) {    if (idx < 5) {        if ([filterSet containsObject: obj]) {            return YES;        }    }    return NO;}; 

Another example Apple provide :

__block BOOL found = NO;NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];NSString *string = @"gamma"; //we provide below a way of how to enumerate, using our own compare logic[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {    if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {        *stop = YES;        found = YES;    }}];

As you can see, it takes a little while to have it sink in but once you get it, it's quite simple. I suggest looking at Apple's documentation, as well as looking at the referenced APIs to see how they are used. Practice makes perfect. 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.