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修饰符, 仅仅是不能改动对象本身, 可是能够改动对象的属性. 

IOS多线程之Block编程的更多相关文章

  1. iOS多线程之8.NSOPeration的其他用法

      本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...

  2. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  3. iOS多线程之Thread

    多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...

  4. iOS多线程之NSThread使用

    iOS中的多线程技术 我们在iOS开发项目过程中,为了解决UI界面操作不被耗时操作阻塞,我们会使用到多线程技术.在iOS开发中,我们主要会用到三种多线程操作技术:NSThread,NSOperatio ...

  5. (五十五)iOS多线程之GCD

    GCD的全称为Grand Central Dispatch,翻译为大中央调度,是Apple开发的一个多线程编程解决方法. 进程和线程的概念: 正在进行中的程序被称为进程,负责程序运行的内存分配,每一个 ...

  6. iOS多线程之GCD、OperationQueue 对比和实践记录

    [toc] 简介      在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的.但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大时钟速度.因此,芯片制 ...

  7. iOS 多线程之GCD的使用

    在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...

  8. iOS多线程之1.从Thread看多线程的生命周期

      Thread 是多线程中最容易理解,但是使用起来又是最麻烦的一种多线程方法.为什么说容易理解呢?一个NSThread的对象就是一条线程.使用起来麻烦是因为,需要我们自己管理线程的生命周期:创建线程 ...

  9. iOS多线程之NSThread详解

    在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于iOS中除了主线程,其他子线程是独立于Cocoa Touch的,所以只有主线程可以更新UI界面.iOS多线程的使 ...

随机推荐

  1. 数据源与JNDI资源实现JSP数据库连接池实例

    名词解释:JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通 ...

  2. Tomcat7 catalina.out 日志切割

    安装步骤例如以下: 下载(最新版本号)     #  wget http://cronolog.org/download/cronolog-1.6.2.tar.gz 假设下载不了,直接网上查找,ftp ...

  3. Win2008 r2 IIS7.5出现FastCGI进程最近常常失败。请过一会再尝试此请求的解决方法

    错误信息如图所示: 应用程序“PIAOYUN.CC”中的服务器错误Internet Information Services 7.5 错误摘要HTTP 错误 500.0 - Internal Serv ...

  4. mysql-5.7 innodb_buffer_pool刷新机制详解

    一.innodb的脏页刷新机制说明: 1.当innodb中的脏页比例超过innodb_max_dirty_pages_pct_lwm的值时,这个时候innodb就会开始刷新脏页到磁盘. 2.当inno ...

  5. WCF使用net.tcp绑定时的注意事项

    IIS Express没有net.tcp绑定功能,本地测试的话只能使用本机的IIS进行承载,并且需要相应的配置(参见上一篇文章). 算了,直接举一个配置例子吧,懒得写了... <system.s ...

  6. c语言常量指针赋值给变量指针导致警告

    常量指针定义:常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针.指针指向的对象是常量,那么这个对象不能被更改.常量指 ...

  7. SVN 版本服务器搭配全过程详解(含服务端、客户端)

    1.为什么要用VisualSVN Server,而不用Subversion? 回答: 因为如果直接使用Subversion,那么在Windows 系统上,要想让它随系统启动,就要封装SVN Serve ...

  8. 【Android】4.0 Android项目的基本结构

    分类:C#.Android.VS2015: 创建日期:2016-02-06: 修改日期:2016-02-27 一.简介 第3章虽然通过百度地图应用展示了你可能感兴趣的内容,但是,如果你是一个初学者,一 ...

  9. Linux 监控分析

    一.硬件基础 Cpu   逻辑的处理.计算.判断 现代分时多任务操作系统对 CPU 都是分时间片使用的:比如A进程占用10ms,然后B进程占用30ms,然后空闲60ms, 再又是A进程占10ms,B进 ...

  10. CDN技术详解笔记

    1.影响网络传输的四个因素(1)“第一公里”:网站服务器接入互联网的链路所能提供的带宽.(2)“最后一公里”:用户接入带宽.(3)对等互联关口:不同网络之间的互联互通带宽.(4)长途骨干传输:首先是长 ...