1. Before using block, the block hands should be sentenced to empty processing.
No empty direct use, once the pointer is empty directly generates a crash.
if (!self.isonlynet) { if (Succblock = = NULL) {//////after using block, do a null processing return; } ID data = [nskeyedunarchiver unarchiveobjectwithfile:[self favoritefile]]; if ([Data Iskindofclass:[nsmutablearray class]]) { succblock (data,yes); } else{ Succblock (nil,yes); }}
2, in the MRC compilation environment, block if as a member parameter to copy the block on the stack to copy to the heap (see below for a reason reference)
3, after the block used to do, the block pointer to do the assignment of NULL value, if it is the MRC compilation environment, to first release the Block object.
Block is a member variable of a class object, and it is possible for a block person to use a class object to participate in an operation in a block to produce a circular reference.
Assigning a block to null is an important way to remove a circular reference. (You can't just do a null-value operation in Dealloc, so that the resulting circular reference will not be destroyed)
typedef void (^SUCCBLOCK) (ID data), @interface Networkclass {successblock _sucblock;} @property (nonatomic,assign) BOOL propertyuseincallback;-(void) Requestwithsucblock: (Successblock) callbackblock;@ End @implementation networkclass-(void) Requestwithsucblock: (Successblock) callbackblock {_sucblock = Callbackblock; MRC under: _sucblock = [callbackblock copy]; The copy block will be recycled on the stack. }-(void) Netwrokdataback: (ID) data {if (data! = Nil && _sucblock! = NULL) {_sucblock (data); }//MRC: To first [_sucblock release]; (previous copy) _sucblock = nil; Importent: After use, the block is assigned a null value, Dereference!!!} @end//======================= The following is a consumer =========================== @implementation usercode-(void) temporarynetworkcall{Networkclass *netobj = [[Networkclass alloc] init]; Netobj.propertyuseincallback = NO; [Netobj requestwithsucblock: ^ (id data) {//because the block references netobj pointers so there is a circular reference, and because the block is passed as a parameter to the object, the compiler will not error. Therefore, Networkclass must assign the block of the member variable a null value after the block is used. if (NetOBj.propertyuseincallback = = YES) {//do Something ...} }];} @end
There is also a modification to the block interface design, the possible variables as parameters to the block, from the design to solve the problem of circular reference.
If the above network class is designed to look like this:
@class netowrkclass;typedef Void (^succblock) (Networkclass *anetworkobj, id data); @interface networkclass//...@ End@implementation networkclass@end @implementation usercode-(void) temporarynetworkcall{ networkclass *netObj = [[Networkclass alloc] init]; Netobj.propertyuseincallback = NO; [Netobj requestwithsucblock: ^ (networkclass *anetworkobj, id data) { //There are already netobj objects in the parameter, the user no longer has to refer to the pointer from outside the block. if (anetworkobj.propertyuseincallback = = YES) { //do Something ... } }];} @end
4. Before adding self or member variable to block, the user must first change to __weak
5. In a multithreaded environment (where the weakself in a block is likely to be refactored), you need to turn self into a strong pointer, avoiding the Self object being refactored when running to a critical step.
The fifth article together has a noun called weak–strong dance, from the WWDC Session #322 (objective-c advancements in Depth)
The following code comes from Afnetworking, a classic that uses Weak–strong dance.
__weak __typeof (self) weakself = self; Afnetworkreachabilitystatusblock callback = ^ (Afnetworkreachabilitystatus status) { __strong __typeof (weakSelf) Strongself = weakself; Strongself.networkreachabilitystatus = status; if (strongself.networkreachabilitystatusblock) { strongself.networkreachabilitystatusblock (status); }};
Review the above code, there is a lot of mystery.
First line: __weak __typeof (self) weakself = self;
As mentioned in the previous article fourth, in order to prevent callback internal to self strong reference, weak a bit.
It uses __typeof (self), which involves several points of knowledge:
A. Differences between __typeof, __typeof__ and typeof
En ~ ~ They are not different, but this involves a past, in the early C language did not typeof this keyword, __typeof, __typeof__ is in the C language of the extension of the keyword when it appears.
typeof is a modern GNU C + + keyword, from the root of objective-c that he actually comes from C, so afnetworking uses a keyword that inherits from C.
B. For the old LLVM compiler above this sentence will compile error, so in the early Arc users popular __typeof (&*self) This style, for the following reasons
The general argument is that the old LLVM compiler will escape __typeof to the XXX class name *const __strong __strong and the preceding __weak keyword to the modifier of the pointer, so add &* to the pointer decoration.
The third line: __strong __typeof (weakself) strongself = weakself;
According to the previous fifth article to return to strong, here __typeof () is written in weakself, it is not a problem to write self, because TypeOf is the compile-time to determine the variable type, so here write self will not be circular reference.
IV Line, if you do not turn into strongself and use weakself, after a few sentences, it is possible that after the execution of the fourth sentence, the object of self may be deconstructed, and then the subsequent stausblock is not executed, resulting in a logic error.
In the last fifth line, the block is empty before use.
Write in the end, read good open Source Library source code is to improve the personal level of a good way to see where you do not know to find out will get more.
Reference:
http://blog.csdn.net/fhbystudy/article/details/17350951
Http://stackoverflow.com/questions/10892361/generic-typeof-for-weak-self-references
Http://stackoverflow.com/questions/14877415/difference-between-typeof-typeof-and-typeof-objective-c
http://rocry.com/2012/12/18/objective-c-type-of/
http://fuckingblocksyntax.com/This is a tool site that I use every time I write a block.
5 things to consider about block usage