Objective-C的Block浅析

作者: 油菜小白 | 来源:发表于2016-04-20 16:00 被阅读56次
  • 本文的写作目的是为学习记录,同时分享给大家,希望大神能够对文中错误的理解进行指正。
  • 如果文章内容涉及到其他已经发表了,但文章中又未提及转载事项,请及时与本人联系。
  • 本文为个人理解,如果部分知识点与真实情况有出入,请忽略本文。

1 了解Block

1.1 概念

  • 带有局部变量的匿名函数(代码块)。
  • 使用Blocks可以不声明C++和Objective-C类,也没有使用静态变量、静态全局变量或全局变量时的问题,仅用编写C语言函数的源代码量即可使用带有局域变量的匿名函数。

1.2 语法

^【返回值类型】【(参数列表)】表达式

其中“【】”内的内容为可省略内容。

  • 其中,返回值类型、参数列表都可以省略。
  • 即使有返回值,也可省略返回值类型,编译器会自动识别返回值类型(NSObject或者void)。

例如:

^void (id testObj) {
    testObj = [[NSString alloc] initWithString:@"This is a iOS Block test!"];
    NSLog(@”%@”,testObj);
}
  • 创建Block,其实是系统自动创建了一个函数,而Block的赋值其实就是将该函数的指针进行存储、传递,类似函数指针赋值(Block赋值,下文会讲到)。

2 Block的用法

2.1 Block类型变量

在Block语法下,可将Block代码块赋值给Block类型的变量。即整个Block代码块可以作为“值”赋值,赋值对象为声明为Block类型的变量。

2.1.1 以Block的返回值作为赋值对象

这种类型再熟悉不过,与普通的函数类似,将函数中return的值作为赋值对象。
例如:

int testInt = ^int {
    return 7;
};

2.1.2 以Block作为赋值对象

  • 在Block语法下,可将Block代码块赋值给已声明为Block类型的变量。

例如:

//声明Block类型变量
int (^testBlk)(int);
//声明Block类型变量,语法为“ 返回值类型 (^Block代码块名称)【(参数类型列表)】”
//将Block代码块赋值给Block类型变量
testBlk = ^(int count){
    return count + 1;
};
  • 在Block语法下,可将Block代码块作为函数的传递参数。

例如:

void testFunction(Bool testBool, int (^testBlk)(int)){ 
    if (testBool) {
        testBlk;
    }
}
  • 在Block语法下,可将Block代码块作为函数的返回值。

例如:

int (^testBlk)(int) testFunction(){
    return ^(int count) { return count + 1;};
}
  • 用typedef声明Block类型,利于代码可读性。

例如:

//声明Block类型,作为Block的参数类型
typedef int (^testBlockType)(int);
int testInt = 0;
//作为传递参数时
void testFunction(testBlockType testBlk){
    testBlk = ^(int count) { return count + 1;};
    testInt = testBlk(10);
}
//作为返回值时
testBlockType testFunction(){
    return (^(int count) { return count + testInt;});
}

2.2 在Block中,截获自动变量

在Block的代码块中,截获代码块之外的变量,其变量值、使用方式须遵守Block语法的规则。

2.2.1截获自动变量

  • Block中,Block代码块截获的自动变量值,是保存在该自动变量的瞬间值。

例如:

int testInt = 0;
void (^blk)() = ^{printf(“value = %d”,testInt)}; 
blk();
//此处打印结果为:value = 0
testInt = 1;
blk();
//此处打印结果为:value = 0
  • Block中,截获自动变量后,不能改写该变量的值。

例如:

int testInt = 0;
void (^blk)() = ^{ testInt = 1;}; 
blk();
//此处报错。在Block代码块中,无法改写非该Block内部自动变量的值。

2.2.2 __block说明符

如果需要在Block代码块中改写该Block之外的自动变量的值,需要在该自动变量上附加__block说明符。
例如:

__block int testInt = 0;
void (^blk)() = ^{ testInt = 1;}; 
blk();

参考:

  • 《Objective-C高级编程 iOS与OS X多线程和内存管理》【日】Kazuki Sakamoto Tomohiko Furumoto 著 黎华 译

相关文章

  • Objective-C的Block浅析

    本文的写作目的是为学习记录,同时分享给大家,希望大神能够对文中错误的理解进行指正。 如果文章内容涉及到其他已经发表...

  • iOS-2 Block

    block块 系列文章: iOS Block浅浅析 - 简书 iOS Block实现原理 iOS Block __...

  • 如果使用Block在Objective-C和Swift中

    A Block in Objective-C? A Block in Swift?

  • 浅析Objective-C之block

    番外 18年和几个开发哥们自主创业,围绕着区块链相关做了整整一年,最终被市场淘汰,只能说:敬畏市场!!!经过一番思...

  • iOS Block

    block 是objective-c对C做的扩展,使用block可以更好的简化objective-c编程,可以理解...

  • block本质

    探究block本质fishhookHook Objective-C Block with Libffi如何使用li...

  • block原理

    c语言中的闭包 block解答题 block结构 唐巧之谈Objective-C block的实现

  • 好文章

    block 理解 Objective-C Method Swizzling

  • Objective-C block 深入了解

    Objective-C block 深入了解

  • Block

    Block 是 Objective-C 版本的 lambda 或者 closure(闭包)。 使用 block 定...

网友评论

    本文标题:Objective-C的Block浅析

    本文链接:https://www.haomeiwen.com/subject/ljnzlttx.html