[Master Objective-c] Blocks (block)

Source: Internet
Author: User
[Mastery of Objective-C] block
Reference book: "Mastering Objective-C" [beauty] Keith Lee

table of Contents
Proficient in Objective-C blocks
table of Contents
Block syntax
Vocabulary scope of the block
Block memory management
Use of blocks
Sorting an array using blocks
Parallel programming using blocks
Block syntax
A block is an implementation closure, a function that allows access to variables outside its regular scope. In addition, an Objective-C block is actually an object. It is a subclass of the NSObject class and has the relevant properties of the NSObject class.

Block declaration:

        int (^ oneParamBlock) (int); // declare a block named oneParamBlock, this block receives an int parameter, the return value is also int
        void (^ twoParamBlock) (int, int); // Receive two int parameters, no return value
        void (^ twoParamBlock2) (int parm1, int parm2); // the declaration can include parameter names
        int (^ noParamBlock) (void); // no parameters need to be written in void, can not be omitted
Definition and call of blocks:

        // Assign the block constant to the previously declared block (the parameter and return type must be the same)
        oneParamBlock = ^ (int addend) {
            return addend + 1;
        };
        // Combine the block declaration and definition (if the block constant has no parameters, it can be omitted)
        void (^ noParamBlock2) (void) = ^ {
            NSLog (@ "Hello, World!");
        };

        // block call
        int value = oneParamBlock (5);
        NSLog (@ "% d", value);

        // define and call a block expression
        ^ (NSString * user) {
            NSLog (@ "Greetings,% @!", User);
        } (@ "Earthing");
Use a block constant expression as a parameter to the calling method:

// Create a block type named AdderBlock to be used as a parameter type in the method
typedef int (^ AdderBlock) (int);

@interface Calculator: NSObject
-(int) process: (int) count withBlock: (AdderBlock) adder;
@end
@implementation Calculator
-(int) process: (int) count withBlock: (AdderBlock) adder {
    return adder (count);
}
@end
        Calculator * clac = [Calculator new];
        int result = [clac process: 2 withBlock: ^ int (int addend) {
            return addend + 1;
        }];
        NSLog (@ "% d", result);
Vocabulary scope of the block
The declaration of a local variable needs to be placed before the block that uses the local variable. By default, local variables cannot be modified in block constant expressions. These variables can be switched to read-write mode using the __block modifier, but the __block modifier cannot be used in combination with auto, register, and static.

        int myVar = 10;
        void (^ logValueBlock) (void) = ^ {
            NSLog (@ "Variable value =% d", myVar);
        };
        logValueBlock ();

        __block int myVar2 = 10;
        void (^ intBlock) (int) = ^ (int amount) {
            myVar2 + = amount;
            NSLog (@ "New value =% d", myVar2);
        };
        intBlock (5);
Block memory management
When the program is run, block constant expressions get stack memory and therefore have the same life cycle as local variables. Therefore they must be copied into a persistent storage area (ie, the heap) to define their use outside of their scope. For example, if you want to get a return value of type block constant from a method or store a block constant, you must copy the blocks to the heap and release them when they are no longer used.

In MRR memory management mode, the copy and release of blocks need to be balanced

        void (^ greetingBlock) (void);
        {
            greetingBlock = [^ {
                NSLog (@ "Hello, World!");
            } copy];
        }
        greetingBlock ();
        [greetingBlock release]; // Free blocks to prevent memory leaks
In ARC memory management mode, the compiler will automatically perform block copy and release operations

Use of blocks
Here are two examples of using blocks:

Sorting an array using blocks
#import <Foundation / Foundation.h>
#include <stdlib.h>

#define ArrayElements 10

int main (int argc, const char * argv []) {
    @autoreleasepool {
        // create an array with random values (0 ~ 99)
        NSMutableArray * numbers = [NSMutableArray arrayWithCapacity: ArrayElements];
        for (int elem = 0; elem <ArrayElements; elem ++) {
            unsigned int value = arc4random ()% 100;
            [numbers addObject: [NSNumber numberWithUnsignedInt: value]];
        }
        NSLog (@ "Values:% @", numbers); // record unsorted values

        // Sort array values in ascending order
        [numbers sortUsingComparator: ^ (id obj1, id obj2) {
            if ([obj1 integerValue]> [obj2 integerValue]) {
                return (NSComparisonResult) NSOrderedDescending;
            }
            if ([obj1 integerValue] <[obj2 integerValue]) {
                return (NSComparisonResult) NSOrderedAscending;
            }
            return (NSComparisonResult) NSOrderedSame;
        }];
        NSLog (@ "Values:% @", numbers); // Record unsorted values
    }
    return 0;
}
Parallel programming using blocks
#import <Foundation / Foundation.h>
#define YahooURL @ "http://www.yahoo.com/index.html"
#define ApressURL @ "http://www.apress.com/index.html"

typedef void (^ DownloadURL) (void);

// Get the block used to download the URL
DownloadURL getDownloadURL (NSString * url) {
    NSString * urlString = url;
    return ^ {
        // Download URL
        NSDate * startTime = [NSDate date];
        NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
        NSError * error;
        // Note that NSURLConnection has been abolished in iOS9. It is recommended to use NSURLSession, followed by the use of NSURLSession
        NSData * data = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: & error];

        if (data == nil) {
            NSLog (@ "Error loading request% @", [error localizedDescription]);
        }
        else {
            NSDate * endTime = [NSDate date];
            NSTimeInterval timeInterval = [endTime timeIntervalSinceDate: startTime];
            NSLog (@ "Time taken to download% @ =% f seconds", urlString, timeInterval);
        }
    };
}

int main (int argc, const char * argv []) {
    @autoreleasepool {
        // create task request
        dispatch_queue_t queue1 = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_queue_t queue2 = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        // create task group
        dispatch_group_t group = dispatch_group_create ();

        // Get the current time of the metric
        NSDate * startTime = [NSDate date];

        // Create and dispatch asynchronous tasks
        dispatch_group_async (group, queue1, getDownloadURL (YahooURL));
        dispatch_group_async (group, queue2, getDownloadURL (ApressURL));

        // wait until all tasks in the group have completed
        dispatc
h_group_wait (group, DISPATCH_TIME_FOREVER);

        // Retrieve time information for parallel operations and logs
        NSDate * endTime = [NSDate date];
        NSTimeInterval timeInterval = [endTime timeIntervalSinceDate: startTime];
        NSLog (@ "Time taken to download URLs concurrently =% f seconds", timeInterval);
    }
    return 0;
}
Use NSURLSession:

        // NSURLSession may not work properly in a command line program and can be debugged in the iOS environment
        NSURLSession * session = [NSURLSession sharedSession];
        NSURLSessionDataTask * dataTask = [session dataTaskWithRequest: request completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {
            NSLog (@ "123");
            if (data == nil) {
                NSLog (@ "Error loading request% @", [error localizedDescription]);
            }
            else {
                NSDate * endTime = [NSDate date];
                NSTimeInterval timeInterval = [endTime timeIntervalSinceDate: startTime];
                NSLog (@ "Time taken to download% @ =% f seconds", urlString, timeInterval);
            }
        }];
        [dataTask resume];
operation result:

2016-07-14 16: 03: 50.780 BlockConcurrentTasks [20262: 170183] Time taken to download http://www.apress.com/index.html = 1.259164 seconds
2016-07-14 16: 03: 54.485 BlockConcurrentTasks [20262: 170182] Time taken to download http://www.yahoo.com/index.html = 4.965020 seconds
2016-07-14 16: 03: 54.486 BlockConcurrentTasks [20262: 170152] Time taken to download URLs concurrently = 4.965577 seconds
It can be seen that executing tasks in parallel consumes less time than asynchronously.

[Mastery of Objective-C] block
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.