IOS easy to use block (on)


Do not use block iOS programmers, not a qualified programmer
learn block, you don’t want to use cumbersome block proxy
not as difficult as you think, don’t be afraid, don’t be afraid, I join the iOS
bold attempt has been dominated by ARC, so just say here that the use of ARC environment under the

What is block

In fact, block is a code block, the code you want to execute the package in the code block, when the need to call again. Is that block a OC object? The answer is yes

IOS easy to use block (on)
from official documents

the author of the English level 3.9 to translate, “block is a OC object, which means that it can be added to the collection, such as NSArray, NSDictionary”

Definition of block

  1. The block attribute or variable
    format: return type (^block name) (parameter list) / * define properties, the block property can be modified with strong, copy can also use the modified buddy message said the official Apple copy suggested, I checked the document, this is it, but I did not test the difference between copy and strong, we love what what it * / @property (nonatomic, strong) (^myBlock) (void); / / parameters return value @property (nonatomic, strong) void (^myBlock1) (NSString *); / / @ property with parameters (nonatomic, strong) NSString (^myBlock2) * (NSString *) with the parameters and return values; / / / / define variables (^myBlock) (void = Nil); / / parameters return value void (^myBlock1) = nil (NSString *); / / with parameter NSString (^myBlock2) * (NSString *) = nil; / / with parameters and return values
  2. Block is used as method parameters:
    format (block type) parameter name – (void) test: (void) (^) (testBlock//). No return value – (void) test1: (void (^) (NSString *) testBlock//) – (void) test2: with parameters (NSString (* ^ () NSString *)) and the return value parameter testBlock//
  3. The use of typedef typedef void (^myBlock) block (); / / since you can use myBlock to define parameters return value of block typedef void (^myBlock1) (NSString *); / / use myBlock1 to define the parameters of type NSString block typedef NSString (^myBlock2) * (NSString *); / / use myBlock2 to define the parameter type NSString, the return value is NSString block / @property (nonatomic, strong attribute definition) myBlock testBlock; myBlock testBlock = nil / / define variables as parameters; / / – (void) test: (myBlock) testBlock;

Assignment of block

Format: block = ^ return type (parameter list) {}

  1. No parameter has no return value myBlock = ^void (testBlock) {NSLog (@ test);}; / / no return value, void myBlock = testBlock1 (can be omitted) ^ {NSLog (@ test1);}; / / no parameters, you can also omit the parentheses (myBlock testBlock2 = ^{@ NSLog test2 “);};
  2. There is no parameter return value myBlock1 testBlock = ^void (NSString *str) {NSLog (STR);} / / myBlock1 = testBlock ^ void (NSString *str) {NSLog} (STR);
  3. A parameter has a return value of myBlock2 = ^NSString * testBlock (NSString *str) {NSLog (STR) return @ “Hi”;} / / return value can also omit the return type of myBlock2 = testBlock2 ^ (NSString *str) {NSLog (STR) return @ “Hi”;} combat next, we combine a examples of procedures, to look at the block in the actual development of the
    IOS easy to use block (on)

    simple to use in this case involves two controller and a Person controller using tableView contact list: display the contact list, said the new contact controller is a A controller: create a new contact object, called the B Person controller: contacts, two the name and phoneNumber attributes.

Task requirements: click the A controller in the upper right corner of the “new” button to jump to the B controller, the B controller to add contacts, click the “save” button to return to the A controller, and the newly added contacts displayed in the list

The question is, how to transfer data from the B controller to the A controller?

It is not simple, the A controller directly to the contact array is passed to the B controller, B controller, the new contact after added to the array, and then return to the A controller, the viewWillAppear method of A controller in OK refresh table.

Method is feasible, but have to say, quite low, B controller is used to add contacts, as to what the contact array, no need to care, so do not pass the array to the B controller

B controller to do is just a new contact, and then the contact object passed to the A controller, as the A controller to get the contact will do what, it is A thing, and B

See here, many people may have thought of agent, yes, agents can also be achieved, but… Is…, B controller definition protocol declaration agent method, A controller agent, to comply with the agreement, and then realize the proxy method, the B controller in the local call agent method, suitable FML, good trouble there. I do not want to write code, or go back to the farm

Well, no nonsense, into the subject

Use block to transfer data

  1. The.H file in the B controller defines a block property @property (nonatomic, strong) void (Person) (^saveBlock) (Person *) with no return value;
  2. Click on the B controller method calls the “save” button in the block – (IBAction) save: (ID sender) {/ / use predefined class method to create Person object Person *person [Person = personWithName:_nameText.text phoneNumber:_phoneNumberText.text]; / * * before calling the block best to determine whether the block is empty, is not empty call, otherwise the program crashes * / / / the loading force is / /! Self.saveBlock?: self.saveBlock (person); / / general transcription if (self.saveBlock) {self.saveBlock} [(person); self.navigationController popViewControllerAnimated:YES];}
  3. In the A controller to the B controller’s block attribute assignment / / “new” button click on the implementation of the method – (void) newContact *addVC alloc] init] {AddContactViewController = [[AddContactViewController; addVC.saveBlock = (Person *person) ^ {/ / here you can get the B controller to pass over the person object, and then added to the array refresh table [self.contactList addObject:person] [self.tableView; reloadData]; [self.navigationController pushViewController:addVC animated:YES];}}; the three step is to fix, is not very simple, so that the block is not as complicated as you think, since I learned block, have never used the agent, in addition to the system.

Block common minefield – circular reference

There is a special place to use block, circular reference, what is a circular reference? You quote me, I quote you, who does not release who, the object can not be destroyed, take up memory

Let’s look at an example of a circular reference

IOS easy to use block (on)

pay attention to console output, when click “Cancel”, the B controller is destroyed, the dealloc method is called

Note the code to open, and then run

IOS easy to use block (on)

click the Cancel button, B is removed, but the dealloc method is not called, so that the B controller has not been destroyed, why?

The block object is assigned to the B property of the B controller, so there will be a strong reference to block and block, and used self (B controller object) will use the block, the external variables to capture, so block also has a strong reference to the B controller, resulting in a circular reference, who can release

Circular reference solution

How to solve circular references? Very simple, a line of code to get

IOS easy to use block (on)

weakSelf (name of random) instead of self, block self will no longer be on the strong reference
map can also use the __weak __unsafe_unretained pointer, the difference is __weak modified, when the object is destroyed, the pointer will be automatically set to nil, and the modified __unsafe_unretained pointer when the object is destroyed, will become a wild pointer. For the sake of safety, recommend the use of __weak

So simple and easy to use block, you have to learn to do, if you feel the article to help you, please a lot of attention, your attention will be the dynamic update, the author will in the next article, about block in the memory, and the capture of block external variables

Portal: “iOS easy to use block (next)”