function pointer, except it also stores the context the block was created in. Similar to closures, lambdas, and anonymous functions in other languages.
Definition Syntax: ^ returnType (Arguments) { code; } The return type and arguments are optional. GCD provides function pointer variants to the block APIs.
if the variables have the new __block keyword. Global and static variables can be modified without the __block keyword. Blocks automatically retain Objective-C objects, except objects that use the __block modifier. C objects must be manually retained. Beware of retain cycles.
a thread pool. Developers create queues of blocks rather than threads. Uses lock-less exclusion rather than mutual exclusion. Replaces blocking and polling APIs.
class instance, all other methods that synchronize on it will temporarily block incoming messages. You can’t synchronize on the class variable since it is initially nil. Using a custom lock also faces the initialization problem.
locks. Both are most efficient when there is no sharing conflicts, (i.e. when you don’t need them) and don’t scale well. Queues are efficient and scale very well. In fact, queues are most efficient under high conflict.
here. } Fast - No Locks Allows private access Synchronous or Asynchronous Can be extended to access many shared data values at once. @synchronized ([obj sharedVar]) { // Critical code here. } Slow - Recursive Lock Must allow public access Synchronous Only Only single-value access.
multithread. Your app will only be faster if the work is parallelizable. Sometimes a block simply contains a loop, and each iteration can be run independently of the others. So, why not spread the iterations across many threads?
and result in high overhead costs. Solution: Use striding (i.e. have one thread run many iterations). Similar to loop unrolling. You may need to profile your app to find the ideal stride length.
= iterations / stride; // myQueue must be a concurrent queue! dispatch_apply(strideCount, myQueue, ^(size_t idx) { size_t i = idx * stride; size_t stop = i + stride; do { [self doIndependentTask:i++]; } while (i < stop); }); // Pick up any left over iterations. for (size_t i = strideCount - (strideCount % stride); i < iterations; i++) [self doIndependentTask:i];
or 5 must be done. 1.Do some processing. 2.Wrap the completion block in another block. 3.Copy the block if it is going to cross threads (unnecessary with ARC). 4.Pass the completion block to someone else. 5.Execute the completion block.
some pre-processing. [self processPhotoAtPath:photoPath completion:^(NSError * error) { if (error) dispatch_async(dispatch_get_main_queue(), ^{ // Inform user of error }); }]; }
Do some resizing and add a caption, then save the modified photo to a temporary file for memory efficiency. [self uploadProcessedPhotoAtPath:newPath completion:^(NSError * error) { // Delete the temporary file. if (completion) completion(error); }]; }