Block是C语言的扩充功能。带有自动变量(局部变量)的匿名函数。(不带有名称的函数)

非匿名函数:int func(int count);(声明了名称为func的函数)使用:int result =func(10);

匿名函数:


Block语法:

  1. ^返回值类型  参数列表    表达式
      1. ^int        ( int count)    {  return count+1};
  2. 省略返回值:
      1. ^        ( int count)    {  return count+1};
  3. 省略返回值和参数列表:
    1. ^        ()    {  return count+1};或者^{  printf(“1223”);}
  4. 将Block赋值为Block类型变量:

返回值类型(^块名)(参数类型)=^参数列表    表达式

Int    (^blk)    (int)            =^(int count){return count+1;};

按照调用函数的方式调用块对象变量就可以了:

int result = myBlock(4); // result是 28


  1. 在函数参数和返回值中使用block
  • 函数参数:void func(int (^blk)  (int)  ){

}

  • 返回值:int(^func())(int){

Return  ^ (int count)    {  return count+1}

}


2.使用typedef简化(定义别名)

定义: typedef int (^blk_t)(int);

  • 原本:void func(int (^blk)  (int)  ){
  • 简化:void func(blk_t blk)
  • 原本:int(^func())(int){
  • 简化:blk_t func()

原本:typedef int (^MyBlock)(int, int);

int (^minusBlock) (int, int) = ^(int a, int b){

return a - b;

};

int (^multiBlock) (int, int) = ^(int a, int b){

return a * b;

};

下面的代码更简洁

MyBlock minusBlock = ^(int a, int b){

return a - b;

};

        MyBlock multiBlock = ^(int a, int b){

return a * b;

};

  • (1)在类中,定义一个Block变量,就像定义一个函数;
  • (2)Block可以定义在方法内部,也可以定义在方法外部;
  • (3)只有调用Block时候,才会执行其{}体内的代码;

Block的几个特性:

  1. 自动变量值的截获

Int dmy=256;

Int val=10;

Const char *fmt=”val=%d\n”;

Void(^blk)(void)=^printf(fmt,val);};

Val=2;

Fmt=”these values were changed. Val=%d\n”;

blk();

Return 0;

}

输出结果:val=10;


2.修改外部变量(_block说明符)

//将Block定义在方法内部

int x = 100;

void (^sumXAndYBlock)(int) = ^(int y){

x = x+y;

printf("new x value is %d",x);

};

sumXAndYBlock(50);

出现编译错误:error: Variable is not assigning (missing __block type)

这时候给int x = 100;语句前面加上__block关键字即可

__block int x = 100;

这样在Block的{}体内,就可以修改外部变量了。


Block储存域:

程序占用内存分布的结构:

栈区(stack:由系统自动分配,一般存放函数参数值、局部变量的值等。由编译器自动创建与释放。其操作方式类似于数据结构中的栈,即后进先出、先进后出的原则。

堆区(heap:一般由程序员申请并指明大小,最终也由程序员释放。如果程序员不释放,程序结束时可能会由OS回收。

全局区/静态区:顾名思义,全局变量和静态变量存储在这个区域。只不过初始化的全局变量和静态变量存储在一块,未初始化的全局变量和静态变量存储在一块。程序结束后由系统释放。

文字常量区:这个区域主要存储字符串常量。程序结束后由系统释放。

程序代码区:这个区域主要存放函数体的二进制代码

int a = 0; // 全局初始化区

char *p1; // 全局未初始化区

main {

int b; // 栈

char s[] = "abc"; // 栈

char *p2; // 栈

char *p3 = "123456"; // 123456\0在常量区,p3在栈上

static int c =0; // 全局静态初始化区

p1 = (char *)malloc(10);

p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在堆区

strcpy(p1, "123456"); // 123456\0在常量区,这个函数的作用是将"123456" 这串字符串复制一份放在p1申请的10个字节的堆区域中。

// p3指向的"123456"与这里的"123456"可能会被编译器优化成一个地址。


Block的使用:


1.Block传值

将B界面的textField.text传给A界面的Label

A页面:RootViewControllers  B页面:DetailViewControllers

B页面:DetailViewController文件

#import <UIKit/Uikit.h>

typedef void (^DetailBlock)(NSString *);//block取别名。并且在参数列表中将需要传递的参数写形参

@interface DetailViewController : UIViewController

@property (nonatomic, copy) PassingValueBlock passingvalue;//设置block属性(注意使用copy)

@property (weak, nonatomic) UITextField *inputTF;

@end

- (IBAction)BtnAction:(id)sender {

//判断block是否为空

if (self. passingvalue) {

self. passingvalue (self.inputTF.text);

}

[self.navigationController popViewControllerAnimated:YES];

}//点击按钮到A界面

RootViewController.m

@property (strong, nonatomic) UILabel *textLabel;

-(void)handleButton: (NSString*)sender{

DetailViewController *detailViewController = [[DetailViewController alloc]init];

detailViewController.passingValue=^( NSString* str){

self. textLabel.text= str;}

[self.navigationController pushViewController:detailViewController animated:YES];

}


2.Block避免循环引用

由于我们很多行为会导致Block的copy,而当Block被copy时,会对block中用到的对象产生强引用(ARC下)或者引用计数加一(non-ARC下)。

如果遇到这种情况:

@property(nonatomic, readwrite, copy) completionBlock completionBlock;

self.completionBlock = ^ {

if (self.success) {

self.success(self.responseData);

}

}

};

对象有一个Block属性,然而这个Block属性中又引用了对象的其他成员变量,那么就会对这个变量本身产生强应用,那么变量本身和他自己的Block属性就形成了循环引用。在ARC下需要修改成这样:

@property(nonatomic, readwrite, copy) completionBlock completionBlock;

__weak typeof(self) weakSelf = self;

self.completionBlock = ^ {

if (weakSelf.success) {

weakSelf.success(weakSelf.responseData);

}

};

注1:iOS4.3之前版本就用__unsafe_unretained替代__weak

注2:如果是non-ARC环境下就将__weak替换为__block即可

iOS学习之block的更多相关文章

  1. IOS学习之block代码块

    前言: block这个名词对于做一般开发者来说可能会觉得稀奇古怪而非常陌生,但是对于iOS工程师来说,在整个开发中到处都是它的影子,今天一大早觉得在假期学习一下它,对明年的iOS开发工作做个准备,突然 ...

  2. IOS学习4——block代码块

    本文转载自:iOS开发-由浅至深学习block 一.关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想 ...

  3. ios学习笔记block回调的应用(一个简单的例子)

    一.什么是Blocks      Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从ios4.0开始就很好的支持Block. 二. ...

  4. ios学习之block初探

    1. block概念 block是ios4.0+和Mac osX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性.所谓匿名函数,也称闭包函数.即同意创建一个暂时的没有指定名称的函数. 最经经 ...

  5. iOS 学习 - 9.Block 入门

    来自李明杰的视频. block 用来保存一段代码 block 的标志:^ block  跟函数很像: 1).可以保存代码  2).有返回值  3). 有形参 temp1:没有返回值.没有形参的 blo ...

  6. 原 iOS深入学习(Block全面分析)http://my.oschina.net/leejan97/blog/268536

    原 iOS深入学习(Block全面分析) 发表于1年前(2014-05-24 16:45)   阅读(26949) | 评论(14) 39人收藏此文章, 我要收藏 赞21 12月12日北京OSC源创会 ...

  7. 【原】iOS学习47之第三方-FMDB

    将 CocoaPods 安装后,按照 CocoaPods 的使用说明就可以将 FMDB 第三方集成到工程中,具体请看博客iOS学习46之第三方CocoaPods的安装和使用(通用方法) 1. FMDB ...

  8. iOS学习路线图

    一.iOS学习路线图   二.iOS学习路线图--视频篇       阶 段 学完后目标 知识点 配套学习资源(笔记+源码+PPT) 密码 基础阶段 学习周期:24天       学习后目标:    ...

  9. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

随机推荐

  1. RDLC隔行变色的实现

    在RDLC设计页面设置行属性中的Background为: =IIF((RowNumber(Nothing)) Mod 2 =1,"Transparent","#F6FAF ...

  2. 更改make/bison的版本

    一.make版本 1.下载make的压缩包 ftp://ftp.gnu.org/gnu/make/ 2.解压,安装 cd make-x.x ./configuration sh build.sh su ...

  3. java selenium针对多种情况的多窗口切换

    一.通过按钮点击打开的新页面,不涉及到打开多窗口,只要在已有打开的窗口实现切换操作即可 Set<String> winHandels = driver.getWindowHandles() ...

  4. wordpress目录文件结构说明

    wordpress目录文件结构说明   wordpress目录文件结构说明. WordPress文件夹内,你会发现大量的代码文件和3个文件夹wp-admin wp-content wp-include ...

  5. ZACC_DOCUMENT

    method if_ex_acc_document~change. data: wa_extension type bapiparex, ext_value() type c, wa_accit ty ...

  6. touch的属性

    touch命令:建立文件   touch的功能并不是用来创建新文件的,创建文件是touch命令的一个特殊情况,touch是用来修改指定的文件的访问和修改时间属性,如果指定的文件不存在,将建立一个新的空 ...

  7. Python之路,Day7 - 面向对象编程进阶

    本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 经典类vs新式类 把下面代 ...

  8. [划分树] POJ 2104 K-th Number

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 51732   Accepted: 17722 Ca ...

  9. Java日志规范

    前言 一个在生产环境里运行的程序如果没有日志是很让维护者提心吊胆的,有太多杂乱又无意义的日志也是令人伤神.程序出现问题时候,从日志里如果发现不了问题可能的原因是很令人受挫的.本文想讨论的是如何在Jav ...

  10. WinPipe后门程序代码示例(仅限技术交流)

    具体怎么编译,生成执行程序,不懂得先学习C++程序代码编译和集成开发环境. 多的不说了,只有两个代码文件,一个头文件,一个源文件.不多说了,直接上干货. (恶意使用,或者商用,后果自负,与本人无关.) ...