IOS多线程之Block编程

1 什么是block
iOS SDK 4.0開始,Apple引入了block这一特性。字面上说,block就是一个代码块。可是它的奇妙之处在于在内联(inline)运行的时候(这和C++非常像)还能够传递參数。

同一时候block本身也能够被作为參数在方法和函数间传递。这就给予了block无限的可能。

    

对于闭包(block),有非常多定义。当中闭包就是可以读取其他函数内部变量的函数,这个定义即接近本质又较好理解。

对于刚接触Block的同学,会认为有些绕,由于我们习惯写这种程序main(){ funA();} funA(){funB();} funB(){.....}; 就是函数main调用函数A,函数A调用函数B... 函数们依次顺序运行,但现实中不全是这种。比如项目经理M,手下有3个程序猿A、B、C,当他给程序猿A安排实现功能F1时,他并不等着A完毕之后。再去安排B去实现F2,而是安排给A功能F1,B功能F2,C功能F3,然后可能去写技术文档,而当A遇到问题时,他会来找项目经理M,当B做完时,会通知M。这就是一个异步运行的样例。在这种情形下,Block便可大显身手,由于在项目经理M,给A安排工作时。同一时候会告诉A若果遇到困难,怎样能找到他报告问题(比如打他手机号)。这就是项目经理M给A的一个回调接口,要回掉的操作。比方接到电话,百度查询后,返回网页内容给A。这就是一个Block,在M交待工作时。已经定义好。而且取得了F1的任务号(局部变量),却是在当A遇到问题时,才调用运行,跨函数在项目经理M查询百度,获得结果后回调该block。

block是一个特殊的OC对象, 它建立在栈上, 而不是堆上, 这么做一个是为性能考虑,还有就是方便訪问局部变量.
默认情况下block使用到的局部变量都会被复制,而不是保留.
所以它无法改变局部变量的值.
假设在变量面前加上__block, 那么编译器回去不会复制变量, 而是去找变量的地址, 通过地址来訪问变量, 实际上就是直接操作变量.
另外块是在栈上分配的, 所以一旦离开作用域, 就会释放, 因此假设你要把快用在别的地方, 必需要复制一份.
所以在属性定义一个快的时候须要使用copy:  @property (nonatomic, copy) void (^onTextEntered)(NSString *enteredText);
块是不能保留的, retain对块没有意义.
2 block 实现原理
Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。
从计算语言的发展,最早的goto,高级语言的指针,到面向对象语言的block,从机器的思维,一步步接近人的思维,以方便开发者更为高效、直接的描写叙述出现实的逻辑(需求)。
iOS中block实现的探究
谈Objective-C Block的实现
3 block的使用
使用实例
A:cocoaTouch框架下动画效果的Block的调用
动画效果是IOS界面重要的特色之中的一个。当中CAAnimation是全部动画对象的抽象父类。作为新人,使用较多的是UIView下的动画方法(类方法)。

使用UIView下的动画,有以下几个方法。

方法一:设置beginAnimations
当中memberView为须要加入的子视图的视图,mivc.view为子视图,在使用的时候,须要将这两个地方替换
须要注意的是。一定要使用[UIView commitAnimations];动画才会生效
通过[UIView setAnimationDuration:1]; 设置持续时间。

方法二:
在IOS4.0后,我们有了新的方法,+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion,依旧是UIView的类方法,但使用到了Block对象。Block对象是一组指令,能够传递(像变量一样),能够把它想像成C语言的函数指针。

[UIView transitionWithView:self.view
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ [self.view addSubview:yellowView.view]; }
completion:NULL];
B:
使用typed声明block
typedef void(^didFinishBlock) (NSObject *ob);
这就声明了一个didFinishBlock类型的block,
然后便可用
@property (nonatomic,copy) didFinishBlock  finishBlock;
声明一个block对象,注意对象属性设置为copy,接到block 參数时,便会自己主动复制一份。 
__block是一种特殊类型。
使用该keyword声明的局部变量,能够被block所改变,而且其在原函数中的值会被改变。
C:1 使用block和使用delegate完毕托付模式有什么长处?
block不同其他变量的原因在于它不是一个单一变量, 而是一个方法,
我们要传递的是一个代码块,而且这个代码块能够存在參数,
这个參数并非在定义block的时候就赋予值, 而是我们在实际执行block的时候才赋予值. 
因此对于有參数的block,当我们传递过去的时候, 它的须要接收方提供对应的參数才干执行, 
这么做我们就能够在A类为B类将来会发生的事件提前做优点理的方法,即使我们还没有这些事件的详细參数.
某种意义上将这样就不须要两者之间的托付关系.
托付关系就是B类发生一个事件后,通知A类,让A类再针对这个事件进行一些处理
而使用block,则是A已经提前将这个事件的处理方法告诉了B类, 等时间发生的时候, B类无需通知A类, 直接执行实现设置好的处理方法(block)就可以.
假设你在执行一个方法的时候又想告诉这种方法在某一特定情况你还要怎么做的话, 就能够使用Block.
D:
GCD:
GCD主要使用block来取代托付模式,使程序变得简洁,同一时候执行效率也得到提高.
复制代码
static int clickNum = 0;
self.Mylabel = [[UILabel alloc]init];
while (clickNum <20) {
dispatch_async(dispatch_get_main_queue(), ^{
self.Mylabel.text = [NSString stringWithFormat:@"%d",clickNum++];//UI的绘制必须在主线程中
});
[NSThread sleepForTimeInterval:1];
}
复制代码
关于block和GCD编程能够參考这篇文章:
还有这篇文章
ARC和非ARC中block的差别:
ARC下Block何时会从栈自己主动被拷贝到推, 以及__block和__weak的使用问题
因为Block是默认建立在栈上, 所以假设离开方法作用域, Block就会被丢弃, 在非ARC情况下, 我们要返回一个Block ,须要 [Block copy];
在ARC下, 下面几种情况, Block会自己主动被从栈拷贝到堆:
1.被运行copy方法
2.作为方法返回值
3.将Block赋值给附有__strong修饰符的id类型的类或者Blcok类型成员变量时
4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中传递的时候.
对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block中有用的对象:
__block id blockSelf=self;
self.blk=^{
NSLog(@"%@",blockSelf);  //在非ARC下对于栈上的_block对象, Block不会对其复制, 只使用, 不会添加引用计数.
};
对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block中有用的对象:
__weak id weakSelf=self;
self.blk=^{
NSLog(@"%@",weakSelf);
};
假设要在ARC下, 为了防止循环引用, 使用__block来修饰在Block中有用的对象,仍然会被retain, 所以须要多做一些设置
__block id blockSelf=self;
self.blk=^{
NSLog(@"%@",blockSelf);
self.blk=nil;   //blk被释放, blk仅仅有的blockSelf也就被释放了
};
blk();   //而且一定要执行一次, 否则不能被释放
这样就使blk断开了与blockSelf的持有关系.
这么多优点是能够自己控制对self的持有时间.
只是在最新的ios版本号中, 这些会始终被已叹号形式提示存在循环引用问题. 
这样的书写方式不被推荐. 除非你要在block中改动__block的指针指向.
事实上我们用使用__weak修饰符, 仅仅是不能改动对象本身, 可是能够改动对象的属性. 

转载于:https://www.cnblogs.com/liguangsunls/p/6702195.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python查找两个数组中相同的元素_匹配两个numpy数组以找到相同的元素

使用熊猫&#xff1a;import pandas as pdid1 pd.read_csv(id1.txt)id2 pd.read_csv(id2.txt)df id1.merge(id2.sort_values(byID2).drop_duplicates(ID2).rename(columns{ID2:ID1}))print(df)产生&#xff1a;^{pr2}$对于大型数据集&#xff0c;您可能需要执行以下操作&…

Spring3系列7- 自动扫描组件或Bean

原文地址 &#xfeff;&#xfeff;http://www.cnblogs.com/leiOOlei/p/3547589.html 一、 Spring Auto Scanning Components —— 自动扫描组件     1. Declares Components Manually——手动配置component 2. Auto Components Scanning——自动扫描组件 3…

数据插不进mysql_数据插入不进数据库里面去。

1&#xff1a;index.php提交到&#xff1a;index_ok.php2:连接数据库文件&#xff1a;conn.php<?php $idmysql_connect("localhost","root","root")ordie(连接失败:.mysql_error());if(mysql_select_db("db_databas...1&#xff1a;ind…

Android_Kotlin 代码学习

https://github.com/ldm520/Android_Kotlin_Demo转载于:https://www.cnblogs.com/simadi/p/6704864.html

liberty配置mysql数据源_Bluemix Liberty server.xml MySQL数据源配置

如果要连接到mysql数据库并希望 manually 在server.xml中提供凭据&#xff0c;则可以执行以下操作&#xff1a;server.xml中&#xff1a;URL"jdbc:mysql://1.2.3.4:3306/db"password"mypassword" user"admin" />name"MySQL Connector&qu…

CI Weekly #17 | flow.ci 支持 Java 构建以及 Docker/DevOps 实践分享

这周一&#xff0c;我们迫不及待写下了最新的 changelog —— 项目语言新增「Java」。创建 Java 项目工作流和其它语言项目配置很相似&#xff0c;flow.ci 提供了默认的 Java 项目构建流程模版&#xff0c;快去试试吧&#xff5e; 最近 flow.ci 2017 招聘计划正式启动&#xff…

mysql mgr 配置_MySQL5.7 MGR安装配置

MySQL5.7 MGR安装配置一、服务器规划mysql_mgr_01192.168.10.223mysql_mgr_02192.168.10.224mysql_mgr_03192.168.10.225二、配置文件1. mysql_mgr_01[rootmysql_mgr_01 tmp]# cat /etc/my.cnf[mysqld]sql_mode STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_D…

你让我怎么说

小组长分配任务,优化首页列表加载响应时间, 涉及更改一同事代码,遇到某个模型命名不解,UserInfoId和CurrentUserInfoId,问这两个干啥使, 答曰UserInfoId是用户的Id,CurrentUserInfoId不知道谁加的, 不解,问道"你写的方法你不知道?", 答曰,不知.后发现是另外一同事共…

python选取tensor某一维_Pytorch的Tensor操作(1)

类型推断torch.randn()&#xff1a;随机初始化a.type()&#xff1a;返回类型type()&#xff1a;返回基本类型isinstance() &#xff1a;检查类型cuda会影响数据类型标量维度(dimention)为0的标量标量的shape&#xff1a;返回类型为【】(空的list)&#xff0c;返回长度也为0a.di…

201521123014 《Java程序设计》第8周学习总结

201521123014 《Java程序设计》第8周学习总结 1. 本周学习总结 1.1 以你喜欢的方式&#xff08;思维导图或其他&#xff09;归纳总结集合与泛型相关内容。 泛型&#xff08;编写的代码可被不同类型的对象所重用&#xff09; Java中一个集合可以放任何类型的对象&#xff0c;因为…

java remove all_如何使用Java List等集合类的removeAll方法

展开全部List等集合类的removeAll方法&#xff0c;API文档描述如下e69da5e6ba9062616964757a686964616f31333361303062&#xff1a;boolean removeAll(Collection> c)从列表中移除指定 collection 中包含的其所有元素(可选操作)。用法案例如下&#xff1a;List list1 new A…

【4.0】jdbcTemplate

1.什么是jdbcTemplate? 2.使用jdbcTemplate 3.crud操作 参考博文&#xff1a;http://blog.csdn.net/u014800380/article/details/64125653 4.采用配置文件的方式使用jdbcTemplate 参考博文&#xff1a;http://suyanzhu.blog.51cto.com/8050189/1563219/ 参考博文原文&#x…

java 默认排序方式_Java Collections.sort()实现List排序的默认方法和自定义方法

1.java提供的默认list排序方法主要代码&#xff1a;list list new arraylist();list.add("刘媛媛");list.add("王硕");list.add("李明");list.add("刘迪");list.add("刘布");//升序collections.sort(list,collator.getinst…

java random算法_负载均衡--随机算法(Random)

随机算法是指&#xff1a;从服务器列表中&#xff0c;随机选取一台服务器进行访问。由概率论可以得知&#xff0c;随着客户端调用服务端的次数增多&#xff0c;其实际效果趋近于平均分配请求到服务端的每一台服务器&#xff0c;也就是达到轮询的效果。一、算法描述假设有 N 台服…

Mysql group by 问题

根据标准sql规定&#xff0c;select字段&#xff08;除聚合函数与&#xff09;必须跟在group by后&#xff0c;但mysql除外&#xff0c;即select * from table a group by a.property 无报错 聚合函数如下&#xff1a; 1. avg() 取其平均数 2.count() 取其数量,返回值为int 3.…

java io体系_java IO流的体系结构图

常用字节流字符流字节流 InputStream 字符流 ReaderFileInputStream BufferedReaderFilte…

jetty java 禁用目录列表_java – 如何禁用Jetty的WebAppContext目录列表?

我将Jetty(版本7.4.5.v20110725)嵌入到java应用程序中。我使用Jetty的WebAppContext在./webapps/jsp/中提供JSP页面&#xff0c;但是如果我访问localhost&#xff1a;8080 / jsp /我获取了Jetty的目录列表&#xff0c;以获取./webapps/jsp/的所有内容。我已经尝试将dirAllowed参…

Arch Linux 安装总结

这篇随笔的目的&#xff1a; 这篇是我今天重新安装后&#xff0c;觉得每次都看别人的来复制&#xff0c;太麻烦了&#xff0c;每次自己解决的一些问题&#xff0c;又不能及时记录下来&#xff0c;导致每次都又需要一通乱找&#xff0c;肯定比第一次开始搜索的要快&#xff0c;但…

java空心正方形代码_从Java中的用户输入绘制空心星号正方形/矩...

我正在尝试创建一个程序,要求用户提供正方形/矩形的宽度和长度尺寸,然后使用#符号将其绘制出来.我几乎了解了,除了我似乎不太了解矩形的右边以正确打印出来…这是我的代码&#xff1a;import java.util.Scanner;public class warmup3{public static void main(String[] args){i…

2017.4.17------软件测试的艺术+整理以前的摘记

2017.4.17 以下内容来自《软件测试的艺术》 第1页——14页。供自己学习使用。 第一章 软件测试&#xff1a;就是一个过程或一个系列过程&#xff0c;用来确认计算机代码完成了其应该完成的功能&#xff0c;不执行其不该有的操作。 第二章 测试人员需要有正确的态度。每当测试一…