[Note] Effective OC - Item 46~48

Chapter 6. Blocks and Grand Central Dispatch

<br />


Item 46: Avoid dispatch_get_current_queue

<br />
这一节讲dispatch_get_current_queue可能会引起的死锁问题。这是一个已经废弃的方法。
主要原因就是不同的queue之间可以以嵌套的形式构成一个树状的结构。比如如果存在A->B这样的父子关系,在B中采用同步操作的话,会把A锁死,就和在主线程进行一个向主队列同步派发的操作是一样的。而dispatch_get_current_queue只能判断当前的queue,不能判断这种队列嵌套关系,所以无法避免这种死锁。书中给的例子:

dispatch_sync(queueA, ^{
   dispatch_sync(queueB, ^{
      dispatch_block_t block = ^{/*…*/};
          if (dispatch_get_current_queue() == queueA) {
              block();
          }
          else {
              dispatch_sync(queueA, block);
          }
     });
});

这里是想做一个判断,想让内部操作不运行在队列A上以免死锁,但是没法做到,因为dispatch_get_current_queue()只能返回队列B。我觉得有点像class cluster的结构,但是class cluster有isKindOfClass:来判断是不是属于某个父类的分支,这里没有这种很直接的方法。
有一个解决方法是使用queue-specific data,给队列关联了一个键值对,根据键来判断是哪个队列,当没有找到关联的值时,会自动沿着树的分支向上查找直到根节点。方法名是dispatch_queue_set_specific。在上面这个例子中,如果给A关联了键值对,在队列B的block中,判断这个键对应的值是否存在,只有不存在时(也就是B不在A的子树中)才把同步操作派发到A,此时就不会死锁了。


Chapter 7. The System Frameworks

<br />


Item 47: Familiarize Yourself with the System Frameworks

<br />
这一节简介系统框架。
一开始提到了动态库与静态库。查了一段解释:

When a C program is compiled, the compiler generates object code. After generating the object code, the compiler also invokes linker. One of the main tasks for linker is to make code of library functions (eg printf(), scanf(), sqrt(), ..etc) available to your program. A linker can accomplish this task in two ways, by copying the code of library function to your object code, or by making some arrangements so that the complete code of library functions is not copied, but made available at run-time.
Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory.
Dynamic linking and Dynamic Libraries Dynamic Linking doesn’t require the code to be copied, it is done by just placing name of the library in the binary file. The actual linking happens when the program is run, when both the binary file and the library are in memory.

iOS的系统框架都是采用的动态库。常见的比如Foundation和CoreFoundation,都是提供基础核心功能的框架,其中后者是C语言框架,两个框架中的数据结构可以toll-free bridging。C语言框架的优点是速度更快,但是需要注意内存管理的问题,因为ARC是只对OC对象起作用。
其他提到的系统框架有CFNetwork, CoreAudio, AVFoundation, CoreData, CoreText, AppKit, UIKit等,基本都听说过吧,然而大多没怎么用过_(:з」∠)_
<br />


Item 48: Prefer Block Enumeration to ‘for’ Loops

<br />
这一节讲对collection对象做enumeration的各种方法。
第一个是for循环。for循环做的是有序遍历。我之前不知道的是,对于无序的collection对象,比如set和dictionary,做for循环时需要先把对象复制到一个有序数组上,然后进行有序遍历。所以这里存在额外空间开销。
快速遍历是我之前最常用的,只要不是一定要用到下标的遍历,都是采用的快速遍历。如果要使自定义的类可以实现快速遍历,需要实现NSFastEnumeration协议。
还可以使用NSEnumerator。这是一个抽象类,只有一个属性allObjects,只有一个方法nextObject。写法很统一,像这样:

NSArray *anArray = /*…*/;
NSEnumerator *enumerator = [anArray objectEnumerator];
id object;
while ((object = [enumerator nextObject] != nil)) {
   // Do something with ‘object’
}

这里第二行,不同的collection定义了返回不同enumerator对象的方法。比如NSDictionary可以返回keyEnumerator和objectEnumerator,也可以返回反向的enumerator。
最后是采用block进行遍历。以NSArray的API为例,提供了三个方法:

- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj,
                                     NSUInteger idx,
                                     BOOL *stop))block
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts
                         usingBlock:(void (^)(ObjectType obj,
                                              NSUInteger idx,
                                              BOOL *stop))block
- (void)enumerateObjectsAtIndexes:(NSIndexSet *)indexSet
                          options:(NSEnumerationOptions)opts
                       usingBlock:(void (^)(ObjectType obj,
                                            NSUInteger idx,
                                            BOOL *stop))block

参数名字已经自解释得很清楚了。block的优势在于,可以在遍历中提供更多的参数供使用,比如idx,比如何时stop。另外如果确定collection里遍历的对象是什么类型,这里的ObjectType可以进行修改,这样编译器就可以知道具体的类型,就会有方法自动补全,当发现调用了本类不存在的方法时可以及时报错。opt这个参数的解释:"A bit mask that specifies the options for the enumeration (whether it should be performed concurrently and whether it should be performed in reverse order)." 就是说可以方便地进行逆向循环和并发循环。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容