22, iOS bottom Analysis - Block (a)

block is more, my understanding of the block is not very thorough in using iOS development, learning about conduct analysis.

Block

1, block several?

Generally, we are able to know the block three ways:

  1. NSGlobalBlock (global block)
  2. NSStackBlock (栈block )
  3. NSMallocBlock(堆block)

But in fact, a total of six kinds of block, and the rest are three kinds of system level:

By looking at the source code libclosure-73 -> data.c file can know

void * _NSConcreteStackBlock[32] = { 0 };         栈block
void * _NSConcreteMallocBlock[32] = { 0 };        堆block
void * _NSConcreteAutoBlock[32] = { 0 };
void * _NSConcreteFinalizingBlock[32] = { 0 };
void * _NSConcreteGlobalBlock[32] = { 0 };        全局block
void * _NSConcreteWeakBlockVariable[32] = { 0 };

Three block used to verify

1.1, heap block

When accessing external variables heap block

    int a = 10;
    void (^block)(void)=^{
        NSLog(@"1233 - %d",a);
    };
    block();
    NSLog(@"%@",block);
// <__NSMallocBlock__: 0x600002d6a0d0> 堆block

1.2, the global block

Do not block access to external variables Global

    void (^block)(void)=^{
        NSLog(@"1233");
    };
    block();
    NSLog(@"%@",block);
// <__NSGlobalBlock__: 0x10ade6150> 全局block

1.3, the stack block

Before heap block copy is the stack block

    NSLog(@"%@",^{
        NSLog(@"1233 - %d",a);
    });
//<__NSStackBlock__: 0x7ffeeeed41b8>

   Before the global block copy or global block

    NSLog(@"%@",^{
        NSLog(@"1233");
    });
//<__NSGlobalBlock__: 0x10a356190>

Note: the above mentioned copy and the copy as previously explained.

1、
    void (^block)(void)=^{
        NSLog(@"1233");
    };
    block();
    NSLog(@"%@",block);
    //这个地方打印的 block = ^{ }; 这个 =(等号)就是copy了一份,所以这样打印是打印的copy之后的block
    
2、
    NSLog(@"%@",^{
        NSLog(@"1233");
    });
    //这样直接打印 ^{ }; 这样打印是没有copy 的block。

 

2, block usage

     1, block chain as the return value to pass parameters
         Masonry
         mark.width.equal (100); program chain
         mark.left.top.height.width.mas_equalTo (100);
         continuous call, while traditional values. This place block as a return value.
         masonry mas_equalTo encapsulates equalTo ()
         - (MASConstraint * (^) (id)) equalTo with a return value id
         The purpose of this is to append operation may continue after .mas_equalTo (100), for example: make.top.equalTo ( loginView.mas_top) .with.offset (0);


     2, block parameters of
         the function may be designed to formula y = f (x) - y = f (f (x)) is a transfer block expression package flexible
         reactive programming RAC

 

3, circular references

#import "LJLBlockViewController.h"

@protocol LJLDelegate <NSObject>
-(void)showName;
@end

typedef void(^LJLBlock)(LJLBlockViewController *);

@interface LJLBlockViewController ()

@property(nonatomic, assign) int age;
@property(nonatomic, copy) LJLBlock ljlBlock;
@property(nonatomic, copy) NSString * name;
@property(nonatomic, strong) NSObject * obj;
@property(nonatomic, weak) id <LJLDelegate>delegate;

@end

 

This place does not constitute a circular reference, but if nested levels deep, then there will be problems.
 See RAC weakly

    self.name = @"LJL";
    [UIView animateWithDuration:1 animations:^{
        NSLog(@"%@",self.name);
    }];

1, the strength of dance (intermediaries)

Intermediary model
holdings described stongWeakSelf -> weakSelf -> self -> ljlBlock -> stongWeakSelf
weakSelf added a weak reference table, holds the self (weakSelf weak references, the reference count is not processed, pointers to only)
because the self reference count is not treated, it will exit when calling the destructor dealloc, self will be set to nil.

Will generally be used directly weakSelf to, but the following code is added wait a dispatch_after if into the page directly back, this time if to the page directly after the return within two seconds, the first call dealloc destructor, this time the first self released, then weakSelf it is nil, then weakSelf.name to become null, and early release. To address this strong need to cite weakSlef. Because stongWeakSelf hold weakSelf, so when self release, weakSelf not immediately released, but the release time and other stongWeakSelf was only set to nil. So you can access the name of the normal side.
// strong-weak-dance dance strength

    self.name = @"LJL";
    __weak typeof(self) weakSelf = self;
    self.ljlBlock = ^(LJLBlockViewController * vc) {
//     2秒后调度
        __strong typeof(weakSelf) stongWeakSelf = weakSelf;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"stongWeakSelf.name = %@",stongWeakSelf.name);
        });
    };
    self.ljlBlock(nil);

2, mediator

Intermediary model, with a broker to place self, exhausted after manually set to nil.
Holding relationship: VC -> self -> block -> VC

    self.name = @"LJL";
    __block LJLBlockViewController * vc = self;
    self.ljlBlock = ^(LJLBlockViewController * myVC) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",vc.name);
            vc = nil;
        });
    };
    self.ljlBlock(nil);

3, parameter passing
through mass participation form, so as not to constitute a holding
mass participation over the value is a copy in-house, will be released in time to block the release.

    self.name = @"LJL";
    self.ljlBlock = ^(LJLBlockViewController * myVC) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",myVC.name);
        });
    };
    self.ljlBlock(self);


Extended:

1、NSObject

This place can not be weak modification of obj, then obj created out because no one constant use so the reference count is released directly out, the relationship does not hold, this time to print out the result is null.
Why xib pulled a weak variable is modified it? Because of this variable xib already hold, so after dragging over to use weak references.

Of course, when the underlying analysis will find (behind when it comes Buried encounter) NSObject helpful weak modified, because it will cause a circular reference holding each other, so what specific modifications need to be determined by the actual situation.

self.obj = [[NSObject alloc] init];
NSLog(@"%@",self.obj);

2, delegate need to use the weak
weak and assign differences:

weak release automatically when set to nil assign not set to nil, it is generally used to assign a modified basic data types. Because the basic data types typically allocated on the stack, the stack memory is handled automatically by the system. Is not set to nil, if there is wild pointer used to modify other will appear after release.
self -> delegate -> self if you do not use the weak will result in a circular reference, it must be self does not hold delegate
self -> delegate -> self

Published 83 original articles · won praise 12 · views 180 000 +

Guess you like

Origin blog.csdn.net/shengdaVolleyball/article/details/104707801
Recommended