Block对象

时间:2022-09-20 12:49:09
背景:回调机制中回调设置代码和回调方法的具体实现无法写在同一段代码中。Mac OS X 10.6和iOS4种引入了Block对象。Block对象看上去是一段代码,但是可以当作数据来传递。
定义Block对象:
^{
     NSLog(@“I’m a log statement within a block!");
}
这段代码看似是一个函数,但是没有函数名,相应的位置只有一个^符号,^符号表示这段代码是一个Block对象。与函数一样,Block对象也可以有实参:
^(double dividend,double divisor){
     double quotient = dividend / divisor;
     return quotient;
}
Block对象也可以有返回值。以上Block对象都只是值,没有名称。为了能够通过名称使用某个Block对象,就必须先将其赋值给Block对象变量。
使用Block对象:
block的变量声明如下
Block对象
为Block变量赋值
Block变量的值一定是一段代码
声明和赋值也可以写在一起
Block对象
typedef
可以用typedef将某个block对象定义为一个新类型,以方便使用。不能在方法的实现代码中使用typedef,应该在文件的顶部或者头文件内。
如,typedef void (^ArrayEnumerationBlock)(id, NSUInterger, BOOL *);
这里定义的是一个新的类型,而不是变量。跟在^字符后面的是类型名称。定义以后可以用ArrayEnumerationBlock devowelizer;这样声明普通变量那样声明Block对象。
返回值
对于有返回值的Block对象,可以像调用函数那样调用Block对象,然后使用其返回值。
double (^divBlock)(double,double) = ^(double k, double j ) {
     return k/j;
}
这段代码首先声明了一个名为divBlock的Block变量,然后将新创建的Block对象赋给了该变量。
Block对象divBlock的示例代码如:double quotient = divBlock(42.0,12.5);
 
内存管理:
Block对象也是在栈中创建并保存的,也就是说,当创建Block对象的函数或者方法完成执行并返回后,相应的Block对象会随着栈帧地释放而被释放。当需要继续保留Block对象时,必须将Block对象从栈靠背至堆。向Block对象发送copy消息可以将其从栈拷贝至堆。
ArrayEnumerationBlock iVarDevowelizer = [devowelizer copy];
iVarDevowelizer指向的对象是基于堆的Block对象,而不是基于栈的Block对象。
在将基于栈的Block对象拷贝至基于堆的Block对象时,Block对象会捕获其使用的变量。对基本类型的变量,捕获意味着程序会拷贝变量的值,并用Blok 参对象内的局部变量保存。对指针类型的变量,Block对象会使用strong特性的引用。这意味着凡是对Block对象用到的对象,都会被保留。
strong特性的引用有可能会导致retain循环问题。当 Block 对象所使用的对象保留了当前的Block 对象时,就会发生retain循环。解决途径:现在 Block对象外声明一个_weak指针,然后将这个指针指向Block 对象使用的对象,最后在 Block 对象中使用这个新的指针。
在 Block对象中,被捕获的变量是常数,程序无法修改变量所保存的值。需要在Block对象内修改某个外部变量,可以在声明相应的外部变量时,在前面加上_block关键字。例如,以下代码可以在Block对象内将外部变量counter的值增1。
_block int counter = 0;
void (^counterBlock)( ) = ^{ counter ++ };
...
counterBlock();//counter增1,数值为2
counterBlock();//counter增1,数值为2
如果这段代码没有使用_block关键字,那么编译器会在 Block 对象的定义处报错,提示修改counter值是无效的。
 

Block对象的更多相关文章

  1. IOS block 对象强引用和若引用

    1. 在block外面这样:__weak MyController *weakSelf = self 或者 __weak __typeof(self) weakSelf = self;是为了防止强引用 ...

  2. iOS 中的 block 是如何持有对象的

    Block 是 Objective-C 中笔者最喜欢的特性,它为 Objective-C 这门语言提供了强大的函数式编程能力,而最近苹果推出的很多新的 API 都已经开始原生的支持 block 语法, ...

  3. block本质探寻五之atuto类型局部实例对象

    说明:阅读本文章,请参考之前的block文章加以理解: 一.栈区block分析 //代码 //ARC void test1() { { Person *per = [[Person alloc] in ...

  4. iOS中block 静态全局局部变量block变量,以及对象,详解!

    //最近总是犯迷糊,关于block对外部变量的引用,今天有时间就写了一下,加深自己的理解,巩固基础知识 1 #import <Foundation/Foundation.h> ; int ...

  5. block,inline和inline-block概念和区别

    总体概念 block和inline这两个概念是简略的说法,完整确切的说应该是 block-level elements (块级元素) 和 inline elements (内联元素).block元素通 ...

  6. Objc Block

    ref1 一.__block 的使用 说明: 在 block 内只能读取在同一个作用域的变数而且没有办法修改在 block 外定义的任何变数,此时若我们想要这些变数能够在 block 中被修改,就必须 ...

  7. iOS 面试题(二):什么时候在 block 中不需要使用 weakSelf --转自唐巧

    问题 我们知道,在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,写下面这样的代码: __weak typeof(self) weakSelf ...

  8. block的循环引用

    什么是循环引用呢? 就是我引用你,你引用我,就会造成循环引用,双方都不会被销毁,导致内存泄漏. _block =  ^{ NSLog(@"%@", self); }; block会 ...

  9. &lbrack;好文要转&rsqb;【关于block使用的5点注意事项】

    1.在使用block前需要对block指针做判空处理. 不判空直接使用,一旦指针为空直接产生崩溃. if (!self.isOnlyNet) { if (succBlock == NULL) { // ...

随机推荐

  1. mysql 优化配置参数详解

    在 my.cnf 文件中 各设置参数的含义如下: innodb_data_home_dir 这是InnoDB表的目录共用设置.如果没有在 my.cnf 进行设置,InnoDB 将使用MySQL的 da ...

  2. ThinkPHP3&period;2判断是否为手机端访问并跳转到另一个模块的方法

    目录结构 公共模块Common,Home模块,Mobile模块 配置Application/Common/Conf/config.php文件 'MODULE_ALLOW_LIST' => 'Ho ...

  3. android 定位的四种方式

    [原文]  开发中对于地图及地理位置的定位是我们经常要用地,地图功能的使用使得我们应用功能更加完善,下面总结了一下网络中现有对于介绍android定位的4种方式,希望对大家有帮助: android 定 ...

  4. 利器&colon; 用Siege做Web服务器压测

    用「Web压测」关键词检索,能找到好多进行压测的工具,比如ab.Http_load.Webbench.Siege这些,不过今天并不是要对这些工具做对比,毕竟我们只是想得到一个结果.本文主要介绍Sieg ...

  5. C&num;面向对象的一些笔记

    抽象 抽象类通常表示一个抽象的概念,提供一个继承的出发点.当设计抽下类时候,尽可能的拥有更多的相同代码,更少的数据. 抽象类.方法用abstract关键字修饰: 抽象成员不能是private. 抽象类 ...

  6. java静态成员的初始化过程

    public class Price{ final static Price INSTANCE = new Price(2.8); static double initPrice = 20; doub ...

  7. Java乔晓松-android中上传图片到服务器Tomcat&lpar;Struts2&rpar;

    在做android开发的时候,有时你会用到图片的上传功能,在我的android项目中,我是选中图片,点击上传多张图片 android客户端上传图片部分的代码如下: package com.exampl ...

  8. Web程序和应用程序服务器&lbrack;转&rsqb;

    转自:http://hi.baidu.com/lclkathy/blog/item/dae3be36763a47370b55a970.html 一 常见的WEB服务器和应用服务器 在UNIX和LINU ...

  9. window下安装mysqldb模块(虚拟环境)

    因为在虚拟环境下安装mysql-python走了许多弯路,各种环境问题,特此记录 直接使用pip安装mysql-python会报错 pip install MySQL-python 可以直接选择非虚拟 ...

  10. OpenStack搭建遇到的问题

    前言:对于像我这种新手来说,搭建OpenStack真的很费劲,因为我总是每配置一个服务,我就想弄懂,后来搭建过程很累人,因此我想了个办法,等我搭建出来再学.我这里将记录我从开始之初到我学习,再到我毕业 ...