Unit 7

来源:互联网 发布:阿里云免费半年邀请码 编辑:程序博客网 时间:2024/06/05 17:55

关于Block的考查

题目为选择题,选择代码能够正常工作的场景:

A. always works.
B. only works with ARC.
C. only works without ARC.
D. never works.

Example A

void exampleA() {  char a = 'A';  ^{    printf("%cn", a);  }();}

Example B

void exampleB_addBlockToArray(NSMutableArray *array) {  char b = 'B';  [array addObject:^{    printf("%cn", b);  }];}void exampleB() {  NSMutableArray *array = [NSMutableArray array];  exampleB_addBlockToArray(array);  void (^block)() = [array objectAtIndex:0];  block();}

Example C

void exampleC_addBlockToArray(NSMutableArray *array) {  [array addObject:^{    printf("Cn");  }];}void exampleC() {  NSMutableArray *array = [NSMutableArray array];  exampleC_addBlockToArray(array);  void (^block)() = [array objectAtIndex:0];  block();}

Example D

typedef void (^dBlock)();dBlock exampleD_getBlock() {  char d = 'D';  return ^{    printf("%cn", d);  };}void exampleD() {  exampleD_getBlock()();}

Example E

typedef void (^eBlock)();eBlock exampleE_getBlock() {  char e = 'E';  void (^block)() = ^{    printf("%cn", e);  };  return block;}void exampleE() {  eBlock block = exampleE_getBlock();  block();}

我是题目与答案的分隔线


例A:A. always works.

首先在函数中声明了一个无名的block,并在声明之后使用()来执行它。(这种语法可能不怎么常见,有个口诀就是:{}分隔作用域,()代码执行。)无疑,它是一个__NSStackBlock__类型的block。此时相当于一个char局部变量在函数结束前访问,结果当然不受ARC/MRC影响。

例B:B. only works with ARC.

示例代码的目的是向数组中添加block,然后访问第一个block元素。同例A,在函数exampleB_addBlockToArray中向数组中添加的block也是__NSStackBlock__的,它的内存分配在栈中,是属于函数的局部变量。所以在函数返回后,访问它会出现野指针错误。这是基于MRC的分析,ARC会自动将block复制到堆中,并将其作为一个__NSMallocBlock__autorelease的block使用。

例C:A. always works.

函数向数组中添加的是一个__NSGlobalBlock__block,相当于全局变量,因此不受ARC/MRC影响。

例D:B. only works with ARC.

函数exampleD_getBlock返回一个__NSStackBlock__block的指针,然后在exampleD执行它。而在MRC中block已经被释放了,因此也会出现野指针错误。ARC能正常工作的原因同例B。

例E:B. only works with ARC.

理由同D。

题目来源:Objective-C Blocks Quiz

为什么OC中很少用@try、@catch?

  1. 能够捕获的异常有限,苹果官方文档也有说明开发者不能依赖于此保证代码的安全性。它不能捕捉像野指针之类的错误。

  2. 在内存管理方式不是GC时,异常容易引起内存管理问题,并且会造成block有额外的开销(捕获异常),使用效率较低。

struct与class的区别是什么?

非常直观的一句话是:struct是值传递,class是引用传递。前者更安全,后者更高效。因为值传递避免了同一个可变类型的数据源引用传递到多个使用场景下出现数据联动的问题,引用传递节约了复制的时间和空间成本。

Swift中,因为其面向协议编程的特性,慢慢弱化了对继承的需求。所以为了让程序更具有安全性,Foundation框架中慢慢用struct取代class了。如StringDictionaryArray等。并且考虑到效率问题,对于集合类的数据传递,容器本身是值传递,即生成一个新的容器对象。而集合中的对象元素依然是引用传递。

struct也开始具有class的各种特征,如属性和方法,可以像构造类那样构造结构体。只是,它没有便利构造器和不能被继承。

HTTPS为什么比HTTP安全?

HTTPS = HTTP + SSL(Secure Socket Layer:安全套接字层)

HTTP协议传输的数据是未经加密的明文,一旦数据内容被第三方截获,数据对其来说就是透明的。而使用HTTPS的服务器会将客户端请求的数据进行加密后传输。而这其中的核心就是网景公司设计的SSL

当客户端需要与实现HTTPS协议的服务器通信时,就会有如下几个步骤:

  1. 客户端使用https开头的url访问服务器,要求与服务器建立SSL连接;

  2. 服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端;

  3. 客户端验证服务器证书信息的有效性,如果有效则继续进行网络连接。然后随机生成AES密钥,使用服务器返回的公钥加密,并将其发送给服务器。

  4. 服务器接收到之后,使用私钥解密,得到客户端随机生成的AES密钥;

  5. 服务器使用AES密钥将客户端请求的数据加密之后传输给客户端;

  6. 客户端使用AES密钥解密获取数据信息。当断开连接时AES密钥作废。

核心:使用RSA非对称加密保证AES密钥的安全性,使用AES对称保证加密的效率和数据的安全。