I. The usage of block in OC can be divided into several types.
1> is used for member properties, saving a piece of code, which can override the proxy value.
For example, to create a Viewcontroller controller, click on the screen to jump to the Modalviewcontroller controller, do not use the proxy block to achieve some functions:
//In the ModalViewController.h file: @property (nonatomic, Strong)void(^valueblock) (NSString *data); In the modalviewcontroller.m file:- (void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (Uievent *)Event{ if(_valueblock) {_valueblock (@"dddd"); }}//in VIEWCONTROLLER.M:- (void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (Uievent *)Event{Modalviewcontroller*MODALVC =[[Modalviewcontroller alloc] init]; Modalvc.valueblock= ^ (NSString *data) {NSLog (@"%@", data); }; [Self PRESENTVIEWCONTROLLER:MODALVC animated:yes completion:nil]; }
2> for parameter passing
//Customize a class for calculations and provide an interface in the CalculatorManage.h file- (Double) Calculator: (int(^) (intresult)) block;//in CALCULATORMANAGE.M.- (Double) Calculator: (int(^) (intresult)) block{_reslut=block (_reslut); return_reslut;} When the outside calls,- (void) viewdidload {[Super viewdidload]; Calculatormanage*mgr =[[Calculatormanage alloc] init]; [Mgr Calculator:^(intresult) {Result+=5; Result*=2; returnresult; }]; NSLog (@"%d", Mgr.reslut); }
3> for return values
//provide interface in CalculatorManage.h file -(void(^) (int value)) add;//in CALCULATORMANAGE.M -(void (^) (int value)) add{ return ^ (int value) { + = value; };} In the external call can be directly used:-(void) viewdidload { [super Viewdidload]; *mgr = [[Calculatormanage alloc] init]; Mgr.add (5);}
4> Notice the circular reference of block (difficulty)
1) Simple circular Reference
Workaround: __weak typeof (self) weakself = self;
@property (nonatomic, strong) void (^block) ();
Block will quote strong pointers from outside
-(void) Viewdidload {
[Super Viewdidload];
typeof (self) weakself = self ; = ^() { typeof(self) strongself = weakself; NSLog (@ "%d", Strongself.age); }; Self.block (); }
-(void) dealloc
{
NSLog ("controller Destruction");
}
I drew a diagram to make it easy to understand,
The <1>modal was first referenced by MODAVC before it came out MODALVC object
After <2>modal, the MODAVC object is referenced by self.presented strong.
After <3>dismiss, there is no strong pointer to strongly reference MODALVC object
<4> but the Block object strongly references the external strong pointer to the access, and all the self becomes a weak pointer to resolve the circular reference
2) Complex circular references
//Scenario 2: When clicking on the controller's view, modal out a controller, modal out of the controller's view and then click, dismiss the current controller, before the controller release, need to complete some other business logic in block blocks, The following is the core part of the Code@property (nonatomic, Strong)void(^block) ();- (void) viewdidload {[Super viewdidload]; _age=1; __weaktypeof(self) weakself =Self ; Self.block= ^() {//Turn the weakself into a strong pointer __strongtypeof(weakself) strongself =weakself; Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (3* nsec_per_sec)), Dispatch_get_main_queue (), ^{NSLog (@"%d", Strongself.age); }); }; Self.block (); }
-(void) dealloc
{
NSLog ("controller Destruction");
}
To make it easier to understand, I drew a picture:
The previous steps are the same as above, starting with the first line of code in block blocks.
1> a strongself is a strong pointer to a MODALVC object
2> in the dispatch block object, there is also a strongself pointing to the MODALVC object
3> entire block block once, strongself hands destroyed
4> but dispatch block object is deferred, so after Modalvcdismiss, it is not destroyed immediately, in this delay of 3 seconds, there is a dispatch block object strong pointer to MODALVC
5> after 3 seconds, the dispatch block blocks execution, the system is no longer strong reference to the dispatch, so the dispatch block destroyed, so it's strongself point to MODALVC strong pointer will also be destroyed
The 6>MODALVC object is completely freed.
5>block Value passing
First, note that global variables, static variables, __block are pointer passing, local variables are value passing
#import <Foundation/Foundation.h>
voidTestinta) { }intA =Ten;intMainintargcConst Char*argv[]) {@autoreleasepool { void(^block) () = ^() {NSLog (@"%d", a); }; A= -; Block (); } return 0;}
Print results What do you guys think it is?
The print result is 20. Because first executes a = 20, at this point A has become 20, and then execute block block, the global variable is a pointer pass, so block blocks once executed, print a result is 20!
6>block Memory Management
1) in the MRC
(1) block does not have access to external variables, it is in the global zone
(2) If an external variable is accessed, the default is in the stack
(3) Copy is used to save in the heap
2) in Arc
If an external variable is accessed, the default is in the heap
OK, the above is I spent nearly a day to tidy up and block related content, block as OC's killer, there are a lot of places worth exploring.
Nevermore 2016.5.29
Block usage and circular references