《企业级ios应用开发实战》一3.5 块编程

简介: 本节书摘来自华章出版社《企业级ios应用开发实战》一 书中的第3章,第3.5节,作者:杨宏焱,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.5 块编程

C语言的运行时特性中包括了块,标准C工作组的 N1370: Apple’s Extensions to C 中(其中也包括垃圾回收)对块进行了定义。作为C语言的扩展,Objective-C在OSX 10.6及iOS 4.0以后支持块语法。块运行时也会被集成到LLVM的compiler-rt子项目存储库中。

3.5.1 块的特点

一些面向对象的动态语言如ruby、groovy,都提供了对块的支持(在groovy中,块被称作为闭包“closure”)。块是用一对{}括号括起来的多个语句的集合。类似于函数,但不同于函数,可以把块作为表达式或变量的一部分,或者作为参数传递。在作为参数传递块时,代码被作为数据的一部分进行传递。
块具有以下特征:
同函数一样,有类型化参数列表。
有返回结果或者要申明返回类型。
能获取同一作用域(与块所在同一作用域)内的状态。
可以修改同一作用域的状态(变量)。
与同一范围内的其他块同享变量。
在作用域释放后能继续共享和改变同一范围内的变量。
除以上特点外,甚至可以复制块并传递到其他后续执行的线程,编译器和运行时负责把所有块引用的变量保护在所有块的拷贝的生命周期内。当然,这已经超出了本章的范围,可以参考苹果官方文档来了解这些内容。

3.5.2 Objective-C 中的块

对于C和C++,块是变量,但对于Objective-C,块仍然是对象。下面简单介绍Objective-C中的块。
1.块变量声明
用^操作符声明一个块变量的开始,分号表示块结束,如下代码所示:

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num  multiplier;
};

块语法比较奇怪,块变量声明的解释如图3-2所示。
screenshot

块变量的声明语句从前至后分为了几部分:
返回值类型,如int、double,如果未显式地声明块的返回值类型,可能会自动从块代码中推断返回类型(通过return语句)。
块变量名用括号括住,块变量名前加^符号。
参数类型用括号括住,多个参数以逗号分隔,如果参数列表为void,而且返回类型依靠推断,可以省略参数列表的void。
等号,将后面的块赋值给前面的块变量(即myBlock)。
以^开头并以;结束的块定义。
块定义中又分为以下两个部分(除去开头的^和结尾的;外):
参数列表,同函数的参数列表。
块体,同函数体。
值得注意的是,块可以使用同一作用域内定义的变量,而函数不行。
一旦声明了块,你可以像使用函数一样调用它:

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num  multiplier;
};
printf ( "%d", myBlock(3));

2.行内块
有时候,你不准备重复使用某个块,因此你不必为它想一个名称。那你可以使用行内块而不用声明为块变量。以下代码来自苹果文档:
// gsort_b类似标准的 gsort_r 函数,但它最后一个参数是一个块。

char myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };
qsort_b(myCharacters, 3, sizeof(char ), ^(const void l, const void r) {
    char left =  (char )l;
    char right =  (char )r;
    return strncmp(left, right, 1);
});
// myCharacters 现在是 { "Charles Condomine", "George", TomJohn" }

在qsort_b 方法调用中,第4个参数就是一个匿名的块(行内块)。匿名块跟块变量不同,它没有变量名,因此你无法重用匿名块。下次调用这个块时,必须把整个块定义的代码再复制一遍。
3.__block关键字
块允许访问本地变量。这很重要。它使得我们在线程间共享变量变得简单,而且,你可以规定一个本地变量是否可以写,这可通过使用__block关键字,这是一种类类似register、auto和static存储类型修饰符。
用__block修饰的变量,可以在所有同一作用域内的块,以及块复制之间共享数据。在指定作用域内的多个块能同时使用共享变量。
如同块,__block变量也使用栈存储。如果使用block_copy拷贝块(或者向块发送copy消息),变量被拷贝到堆里。而且,__block变量的地址随后就会改变。
__block变量有两个限制:不能是可变长度的数组,也不能是包含C99可变长度数组的结构体。
下面显示了__block变量的使用:

__block int x = 123; //  x 是块可写的
void (^printXAndY)(int) = ^(int y) {
      x = x + y; 
      printf("%d %d\n", x, y);
};
printXAndY(456); // 打印出: 579 456
// x 现在的值是:579

下面显示了在块中使用多种类型的变量:

extern NSInteger CounterGlobal;
static NSInteger CounterStatic;
{
      NSInteger localCounter = 42;
      __block char localCharacter;
      void (^aBlock)(void) = ^(void) {
            ++CounterGlobal;
            ++CounterStatic;
            CounterGlobal = localCounter; 
            localCharacter = 'a';
      };
      ++localCounter; 
      localCharacter = 'b';
      aBlock(); 
}
相关文章
|
1月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
160 4
|
2月前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
2月前
|
搜索推荐 IDE API
打造个性化天气应用:iOS开发之旅
【9月更文挑战第35天】在这篇文章中,我们将一起踏上iOS开发的旅程,通过创建一个个性化的天气应用来探索Swift编程语言的魅力和iOS平台的强大功能。无论你是编程新手还是希望扩展你的技能集,这个项目都将为你提供实战经验,帮助你理解从构思到实现一个应用的全过程。让我们开始吧,构建你自己的天气应用,探索更多可能!
77 1
|
28天前
|
API Android开发 iOS开发
深入探索Android与iOS的多线程编程差异
在移动应用开发领域,多线程编程是提高应用性能和响应性的关键。本文将对比分析Android和iOS两大平台在多线程处理上的不同实现机制,探讨它们各自的优势与局限性,并通过实例展示如何在这两个平台上进行有效的多线程编程。通过深入了解这些差异,开发者可以更好地选择适合自己项目需求的技术和策略,从而优化应用的性能和用户体验。
|
1月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
33 2
|
1月前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
59 1
|
2月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
62 5
|
3月前
|
存储 IDE 开发工具
移动应用开发之旅:打造你的首个iOS应用
【9月更文挑战第23天】在数字化浪潮中,移动应用已成为连接用户与数字世界的关键桥梁。本文将带领读者踏上开发属于自己的第一个iOS移动应用的旅程,从理解移动操作系统的核心概念出发,逐步深入到实际的应用构建过程中。通过简洁明了的语言和具体的代码示例,我们将一起探索如何在苹果的iOS平台上实现一个简单的“待办事项列表”应用,让读者不仅能够学习到编程知识,还能体会到将想法转化为现实产品的成就感。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供一个实用的指南,帮助你迈出成为移动应用开发者的第一步。
|
3月前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
71 5