zoukankan      html  css  js  c++  java
  • 【Objective-C 篇】 ☞ 8. block

    block(代码块)

    1.1 什么是block

    • block是iOS中一种比较特殊的数据类型。(可以定义变量、做形参或返回值)
    • block是苹果官方特别推荐使用的数据类型,应用场景比较广泛
      • 动画
      • 多线程
      • 集合遍历
      • 网络请求回调

          在多线程和网络也使用得相当频繁,一般都是作为回调使用!

    • block的作用
      • 和函数一样,用来保存某一段代码,可以在恰当的时间再取出来调用
      • block功能类似于函数(方法),比函数更强大。
      • block是一种数据类型,可以嵌套定义,随时调用。

    Xcode输入 inline 可快速生成(快捷键)

    1.2 block的格式    

      

    • 比较函数、函数指针、block:

           

        如果block没有参数, 那么^后面的()可以省略

    • block案例

    1.3 给block类型取别名(类比函数指针)

         

    变量的名称就是类型名称(即别名)

         

    1.4 block的应用场景

       当前面代码块一样,后面代码块一样,中间的代码块不一样,中间的代码块就用block。

        

    1.5 block的注意事项

    • block中可以定义和外界同名的变量,但是在block中访问的是block中定义的变量(就近原则,和函数一样)

         

    • 在代码块中可以访问外面的变量

        (1)在代码块中可以直接访问和修改非栈区的变量(使用的是同一个变量)

     

          

        (2)栈区的变量可以访问,但默认不能修改(使用的是不同的变量,实际上访问的是自己拷贝的值)

            block中的变量和外界的局部变量并不是同一个变量,block会将外界的变量拷贝一份到堆内存中

            block中使用的外界变量是copy,所以在调用之前修改外界变量的值,不会影响到blockcopy的值

          

        (3)在代码块中修改局部变量编译不通过。怎么在代码块中修改局部变量呢?在局部变量前面加上关键字:__block

             

      

    1.6 面试题:block是存储在堆中还是栈中?

    • 默认情况下block存储在栈中,如果对block进行一个copy操作,block会转移到堆中
    • 如果block在栈中, block中访问了外界的对象, 那么不会对对象进行retain操作
    • 如果block在堆中, block中访问了外界的对象, 那么会对外界的对象进行一次retain

        

    1.7 block的内存泄露体现

    block在copy时都会对block内部用到的对象进行强引用(ARC)或者retainCount增1(非ARC)。

    在ARC与非ARC环境下对block使用不当都会引起循环引用问题。

    一般表现为:

      某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是

         

        

    1MRC情况下,用__block可以消除循环引用。

    2ARC情况下,必须用弱引用才可以解决循环引用问题,iOS5之后可以直接使用__weak,之前则只能使用__unsafe_unretained了,__unsafe_unretained缺点是指针释放后自己不会置空。

     

    什么时候栈上的Block会复制到堆呢?

    • 调用Block的copy实例方法时
    • Block作为函数返回值返回时
    • 将Block赋值给附有__strong修饰符、id类型的类或Block类型成员变量时
    • 在方法名中含有usingBlock的Cocoa框架方法或GCD的API中传递Block时

         

        block很多的用处是跨越两个类来使用的。

        实现两个页面之间的传值:

    • 通过“协议/代理”实现两个页面之间传值
    • 使用block作为property,实现两个页面之间传值

     

    面试题:

        

     

  • 相关阅读:
    SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何实现对三维模型和地形的剖切展示
    SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何正确使用三维地图控件和工程树控件
    SkylineGlobe TerraExplorer for Web 7.1.0版本 接口示例
    如何解决一个从SkylineGlobe5版本升级到7版本遇到的小问题
    Cesium如何通过addImageryProvider方法加载SkylineGlobe Server发布的WMS服务
    SkylineGlobe7.0.1版本 支持SQLite(*.sqlite;*.db)数据库
    SkylineGlobe7.0.1版本 通过鼠标左右平移模型对象
    显示器文字发虚的一种原因
    HttpClient + IIS压缩动态内容
    C# Async Await 注意事项
  • 原文地址:https://www.cnblogs.com/bossren/p/6428935.html
Copyright © 2011-2022 走看看