zoukankan      html  css  js  c++  java
  • Block块

    block的标志:^
    特点:
    1、可以保存代码
    2、有返回值
    3、有形参
    4、调用方式和c语言一样
    5、可以访问外部变量,但不能修改变量的值;如果使用__block关键字修饰的变量才可以。
    1)创建
    格式:
    返回类型  ^block名称(参数类型表)=^(参数表){
         代码;
    };
    block跟函数很像
    a、不带参数
    void (^myBlock)()=^{
         NSLog(@“…000”);
    };
    b、带参数
    int(^sumBlock)(int,int)=^(int a,int b){
         return a+b;
    }
    c、用typedef定义block变量
    typedef int(^)
    定义block变量:
    typedef int(^myblock)(int,int);
    实现(重写):
    myblock sblock = ^(int a,int b){
         return a+b;
    }
    myblock subblock = ^(int a,int b){
         return a-b;
    }
    使用:
    NSLog(@“a+b = %d”,sblock(1,2));
    NSLog(@“a+b = %d”,subblock(5,2));
     
     
    如:
    //定义一个带block参数的函数
    -(void)xxxxxxx:(void(^)(NSString *strr))finishBlock{
        NSLog(@"xxxxxxxx");
        finishBlock(@"........");
        NSLog(@"jjjjjjjj");
    }
    //调用
    - (IBAction)Blockaction:(UIButton *)sender {
        [self xxxxxxx:^(NSString *strr) {
            NSLog(@"%@",strr);
        }];
    }
    结果:
     
     
    6、Block的循环引用 
    1)__weak:表示引用为弱引用。对应在定义property时用的"weak"。弱引用不会影响对象的释放,即只要对象没有任何强引用指向,即使有100个弱引用对象指向也没用,该对象依然会被释放。不过好在,对象在被释放的同时,指向它的弱引用会自动被置nil,这个技术叫zeroing weak pointer。这样有效得防止无效指针、野指针的产生。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑与生成的UI控件。
    2)__strong:表示引用为强引用。对应在定义property时的"strong"。所有对象只有当没有任何一个强引用指向时,才会被释放。

    注意:如果在声明引用时不加修饰符,那么引用将默认是强引用。当需要释放强引用指向的对象时,需要将强引用置nil。

    一个特别要注意的问题

    苹果的文档中明确地写道:

    You should decorate variables correctly. When using qualifiers in an object variable declaration,

    the correct format is:

    ClassName * qualifier variableName;
    

    按照这个说明,要定义一个weak型的NSString引用,它的写法应该是:

    NSString * __weak str = @"hehe"; // 正确!

    而不应该是:
    __weak NSString *str = @"hehe";  // 错误!
    
     
    对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block
    对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1

    不过好在,编译器会及时地给我们一个警告,提醒我们可能会发生这类型的问题:

    对这种情况,我们一般用如下方法解决:给要进入Block的指针加一个__block修饰符。

    这个__block在MRC时代有两个作用:

    • 说明变量可改
    • 说明指针指向的对象不做这个隐式的retain操作 
    一个变量如果不加__block,是不能在Block里面修改的,不过这里有一个例外:static的变量和全局变量不需要加__block就可以在Block中修改。
    在ARC引入后,没有了retain和release等操作,情况也发生了改变:在任何情况下,__block修饰符的作用只有上面的第一条:说明变量可改。即使加上了__block修饰符,一个被block捕获的强引用也依然是一个强引用。
    #include <stdio.h>
    
    int main()
    {
        int b = 5;
        int *a = &b;
        void (^blockFunc)() = ^(){
            int *c = a;
        };
        
        blockFunc();
        
        return 1;
    }
    
    程序中,同为int型的指针,a是被Block捕获的变量,而c是在Block内定义的变量。a和c存在的位置完全不同,如果Block存在于堆上(在ARC下Block默认在堆上),那么a作为Block结构体的一个成员,也自然会存在于堆上,而c无论如何,永远位于Block内实际执行代码的函数栈内。这也导致了两个变量生命周期的完全不同:c在Block的函数运行完毕,即会被释放,而a呢,只有在Block被从堆上释放的时候才会释放。
    
    同上理,如果我们直接让Block捕获我们的myController引用,那么这个引用会被复制后(引用类型也会被复制)作为Block的成员变量存在于其所在的堆空间中,也就是为Block增加了一个指向myController对象的强引用,这就是造成循环引用的本质原因。
     
    //------------------------------------------------------------------------------------
  • 相关阅读:
    TF-IDF基本原理简释
    岭回归(Ridge Regression)、OLS和吉洪诺夫正则化(Тихонов regularization)
    论文笔记[8] Seismic Waveform Classification and First-Break Picking Using CNN
    如何科学地使用keras的Tokenizer进行文本预处理
    集成学习(Ensemble)相关概念及算法(Adaboost,Bagging,Stacking)
    论文笔记 [7] complex-trace analysis for temporal resolution improvement
    关于python的一些笔记 2018-03-01 00:04:54
    Keras文本预处理相关函数简介(text preprocessing)
    python中re模块正则表达式(Regular Expression)的基本用法示例
    循环神经网络(RNN)中的LSTM和GRU模型的内部结构与意义
  • 原文地址:https://www.cnblogs.com/lignpeng/p/5444674.html
Copyright © 2011-2022 走看看