Block-----镜像拷贝

来源:互联网 发布:如何不花钱做网络推广 编辑:程序博客网 时间:2024/06/05 07:24

高能原理传送门

block,指向结构体的指针,同时也相当于结构体+回调函数。

block的定义本质和函数一样,只不过不需要返回函数名。block以签名字符串开始:

^double(double rate,double time){

        

    };

标示返回一个double,以及接受两个同样为double的参数。

 void(^block)(int a,int b)=^void(int a,int b){};

-----------> void(^block)(int a,int b);block=^void(int a,int b){};

理解:

void(^block)(int a,int b)=^void(int a,int b){};

------->    

    typedefvoid(^MyBlock)(int,int);//void(^)(int,int)MyBlock

   MyBlock block=^void(int a,int b){};

最简:无参数无返回值:void(^block)()=^{};


传值:

1.定义Block属性;

例:

@property(nonatomic,copy)void(^childBlock)(NSInteger a);

2.参数加入(传值)(同类)

例:

   self.childBlock(self.clean);

3.调用set

例:外类:

 self.child.childBlock=^(NSInteger a){

    

        NSLog(@"--------------a%ld",a);

        

    };

同类:

    self.childBlock=^(NSInteger a){

  

        NSLog(@"cleanSelf%ld",a);

        

    };


回调:

1.定义Block属性(1.m)

例:

@property(nonatomic,copy)void(^childBlock)(NSInteger a);




2.定义方法(1.m)(关联Block属性)

-(void)cleanWithclean:(NSInteger)clean andChildBlock:(void(^)(NSInteger a))childBlock;

{

   _clean=clean;

    

   _childBlock=childBlock;

    

}


3.调用2方法(2.m),回1.m

[self.childcleanWithclean:100andChildBlock:^(NSInteger a) {

        

        NSLog(@"happy-----%ld",a);

    }];

此时后面的block不走。


4.后续加入(1.m)(传值,另方法或条件中)

    if (self.clean<90) {

   

self.childBlock(self.happy);//此条件或者方法中走到此处,执行block

      

    }


5.走Block(2.m)


其实跟传值的道理是一样的,(携带参数)执行到block的时候,程序回去找set(程序执行到此,需要有一个block,而不是一个空的东西,所以带着参数去找他的内容所在)。


最后,注意:

1.block使用copy是MRR遗留下来的习惯,ARC中可用strong(ARC默认在堆上),相当于copy;


Block回调特性使Block会对其内部的引用对象或者引用属性的对象Retain一次,导致内存泄露。(copy造成强引用)

所以,引用前在外部需用_ _weak修饰转换一下。例: __weakChild *weakSelf=self;

进入block之后:Child *strongSelf=weakSelf;

即:以弱引用引进来,进来之后再转为强引用使用。


2.block捕获的局部变量(镜像拷贝)存在于block所在的堆中,block内定义的变量位于block函数栈中;


MRR(Manual Retain-Release)时代,_ _block两个作用:a.变量可改;b.指针指向的对象不做隐式retain操作;

ARC(Automatic Reference Counting)时代,_ _block仅能说明可改。


3.static变量和全局变量不用修饰亦可修改






0 0