IOS block starts from scratch

Source: Internet
Author: User

IOS block starts from scratch

After iOS4.0, Block was born, it itself encapsulated a piece of code and the code as a variable, through the block () way callback.

Structure of block

Let's start with a simple code to see:

void (^myBlock)(int a) = ^(int a){        NSLog(@"%zd",a);    };    NSLog(@"旭宝爱吃鱼");    myBlock(999);

Output Result:

2016-05-03 11:27:18.571 block[5340:706252] Xu Bao love to eat fish
2016-05-03 11:27:18.571 block[5340:706252] 999

Let's look at the following:

    • VOID: The returned parameter void is not a return value
    • (^myblock): Myblock is the name of the block
    • (int a): This is a parameter list
    • ^ (int a): Incoming parameters

With the simple introduction above, we can easily understand the structure of block, then the following will produce four kinds of block.

Four types of block

There are return values without parameters:

int (^myBlock)() = ^(){        return 999;    };

There are parameters for the return value:

int (^myBlock)(int a) = ^(int a){        NSLog(@"%zd",a);        return a;    };

No return value no parameter:

void (^myBlock)() = ^(){        NSLog(@"旭宝爱吃鱼");    };

No return value has parameters:

void (^myBlock)(int a) = ^(int a){        NSLog(@"%zd",a);    };
Block captures external local variables

Example code:

int a = 10;    void (^myBlock)() = ^(){        NSLog(@"旭宝爱吃鱼");        NSLog(@"%zd",a);    };    NSLog(@"旭宝爱吃鱼");    myBlock();

Operation Result:

2016-05-03 11:43:32.680 block[5406:713702] Xu Bao love to eat fish
2016-05-03 11:43:32.681 block[5406:713702] Xu Bao love to eat fish
2016-05-03 11:43:32.681 block[5406:713702] 10

It is not difficult to see that we can get local variables by using the sample code, so changing the local variable will also change the value within the block.

Example code:

int a = 10;    void (^myBlock)() = ^(){        NSLog(@"旭宝爱吃鱼");        NSLog(@"%zd",a);    };    a = 20;    NSLog(@"旭宝爱吃鱼");    myBlock();

Operation Result:

2016-05-03 11:47:07.669 block[5425:715861] Xu Bao love to eat fish
2016-05-03 11:47:07.670 block[5425:715861] Xu Bao love to eat fish
2016-05-03 11:47:07.670 block[5425:715861] 10

As the results show, the value inside the block will not change, for what?????

Example code:

int a = 10;    a = 20;    void (^myBlock)() = ^(){        NSLog(@"旭宝爱吃鱼");        NSLog(@"%zd",a);    };    NSLog(@"旭宝爱吃鱼");    myBlock();

Operation Result:

2016-05-03 11:49:19.749 block[5450:717309] Xu Bao love to eat fish
2016-05-03 11:49:19.750 block[5450:717309] Xu Bao love to eat fish
2016-05-03 11:49:19.750 block[5450:717309] 20

The answer is understandable.
The value inside the block does not change because the block copy local variables.

This problem is resolved after attempting to change the local variables in the block.
Unfortunately I failed, and when I changed the local variables inside the block, I got an error.
Visualization I want to change the outside local variables what should I do???

Change the local variables of the outside world

Example code:

__block int a = 10;    void (^myBlock)() = ^(){        NSLog(@"旭宝爱吃鱼");        NSLog(@"%zd",a);        a = 20;    };    NSLog(@"旭宝爱吃鱼");    myBlock();    NSLog(@"%zd",a);

Operation Result:

2016-05-03 11:55:02.736 block[5490:721033] Xu Bao love to eat fish
2016-05-03 11:55:02.737 block[5490:721033] Xu Bao love to eat fish
2016-05-03 11:55:02.737 block[5490:721033] 10
2016-05-03 11:55:02.737 block[5490:721033] 20

We only need to add __block before local variables.

Circular references (as I mentioned in the previous blog)

Block is considered an object in iOS development, so its life cycle will not end until the end of the life cycle of the holder. On the other hand, because the block captures the variable mechanism, the object holding the block may also be held by the block, thus forming a circular reference, resulting in both cannot be released:

@implementation CXObject{   void (^_cycleReferenceBlock)(void);}- (void)viewDidLoad{    [super viewDidLoad];    _cycleReferenceBlock = ^{         NSLog(@"%@", self);   //引发循环引用    };}@end

Encountering this kind of code compiler will only tell you there is a warning, many times we ignore the warning, which will eventually lead to memory leaks, both can not be freed. As with the normal variable exists block keyword, the system provides us with the weak keyword used to decorate the object variable, declaring that this is a weak reference to the object, thus solving the problem of circular reference:

__weak typeof(*&self) weakSelf = self;_cycleReferenceBlock = ^{     NSLog(@"%@", weakSelf);   //弱指针引用,不会造成循环引用};
Use block

Before the block appears, the developer implementation callback is basically done by proxy. For example, responsible for the network request of the native class Nsurlconnection class, through a number of protocol methods to implement the event processing in the request. In the latest environment, the use of the nsurlsession has been the block way to handle the task request. Various third-party network request frameworks are also using block for callback processing. This shift is due in large part to the simple use of blocks, clear logic, and flexibility. Next I will complete a network request and then callback processing via block. These callbacks include request completion, download progress

It's a bit of a hassle to make a block declaration in the form of ReturnValue (^blockname) (parameters), and we can use the keyword typedef to type the block name, and then create the block directly from the type name:

@interface cxdownloadmanager:nsobject//block rename typedef void (^cxdownloadhandler) (NSData * receivedata, Nserror * error ); typedef void (^cxdownloadprogresshandler) (cgfloat progress);-(void) Downloadwithurl: (NSString *) URL parameters: ( Nsdictionary *) Parameters Handler: (Cxdownloadhandler) Handler progress: (Cxdownloadprogresshandler) progress;@ End@implementation cxdownloadmanager{Cxdownloadprogresshandler _progress;} -(void) Downloadwithurl: (NSString *) URL parameters: (nsdictionary *) Parameters Handler: (Cxdownloadhandler) handler Progress: (Cxdownloadprogresshandler) progress{//Create Request Object Nsurlrequest * request = [self postrequestwithurl:url param     S:parameters];    Nsurlsession * session = [nsurlsession sharedsession]; Execute Request Task Nsurlsessiondatatask * task = [session datataskwithrequest:request Completionhandler: ^ (NSData * _nullable da TA, Nsurlresponse * _nullable response, Nserror * _nullable error) {if (handler) {Dispatch_async (Dispa Tch_get_main_queue (), ^{handler (data, error);         });    }    }]; [Task resume];} Progress protocol Method-(void) Urlsession: (Nsurlsession *) session Downloadtask: (Nsurlsessiondownloadtask *) Downloadtask didwrited ATA: (int64_t) byteswritten//data bytes per write Totalbyteswritten: (int64_t) Totalbyteswritten//Total data bytes currently written totalbytes Expectedtowrite: (int64_t) Totalbytesexpectedtowrite//expected to receive all data bytes {Double downloadprogress = Totalbyteswritten      /(double) totalbytesexpectedtowrite;  if (_progress) {_progress (downloadprogress);}} @end

By encapsulating the nsurlsession request, passing in a block object that processes the result of the request, the request task is automatically put into the worker thread to execute the implementation, and we call the following in the Code of the network request logic:

#define QQMUSICURL @"https://www.baidu.com/link?url=UTiLwaXdh_-UZG31tkXPU62Jtsg2mSbZgSPSR3ME3YwOBSe97Hw6U6DNceQ2Ln1vXnb2krx0ezIuziBIuL4fWNi3dZ02t2NdN6946XwN0-a&wd=&eqid=ce6864b50004af120000000656fe235f"[[CXDownloadManager alloc] downloadWithURL: QQMUSICURL parameters: nil handler ^(NSData * receiveData, NSError * error) {    if (error) { NSLog(@"下载失败:%@", error) }    else {        //处理下载数据    }} progress: ^(CGFloat progress) {    NSLog(@"下载进度%lu%%", progress*100);}];
Summarize

Block capture variables, code delivery, code inline, and other features give it more than the agent mechanism of the function and flexibility, although it also has a circular reference, not easy to debug traceability and other defects, but undoubtedly its advantages are favored by the code farmers. How to use block more flexibly requires that we continue to use it, explore the understanding to complete

IOS block starts from scratch

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.