美文网首页
Effective Objective-C 2.0 笔记

Effective Objective-C 2.0 笔记

作者: 三三At你 | 来源:发表于2018-07-19 15:52 被阅读0次

Effective Objective-C 2.0

===

第52条 NSTimer引用

  • 使用block语法代替iOS10支持
  • iOS10以前
@implementation NSTimer
+(NSTimer *)ll_scheduledTimerWithTimeInterval:(NSTimeInterval)ti 
                                     block:(void (^)())block
                                      repeats:(BOOL)yesOrNo{
    [self scheduledTimerWithTimeInterval:ti 
                                  target:self 
                                selector:@selector(ll_timerblock:) 
                                userInfo:[block copy] 
                                repeats:(BOOL)yesOrNo];
}
+(NSTimer *)ll_timerblock:(NSTimer*)timer {
    void (^block)() = if(timer.userInfo);
    if(block){
        block();
    }
}
@end

第51条 +load和+initialize

+load +initialize
运行时机 程序启动时 第一次调用时
调用父类 �子类不实现+load不会调用父类+load 子类不实现会调用父类+initialize
分类 分类实现了+load先调基类,再调分类 子类实现了+initialize,先调超类,再调自身,通常要判断类型是否等于自身
实际应用 方法交换 初始化编译时不能确定的全局变量如NSMutableArray,或者单例模式使用前执行必要的初始化动作。

注意事项

  • initialize运行时线程安全,运行线程不确定。
  • 尽量避免在两种方法里面执行耗时操作
    — 尽量避免在两种方法里面调用其他类或方法,有可能会出现互相依赖导致未能正确初始化的情况。

第50条 构建缓存时选用NSCache而非NSDictionary

NSCache NSDictionary
自动删除 Y (LRU) N
拷贝Key N Y
线程安全 Y N

第49条 对自定义其内存管理语义的 collection 使用无缝桥接

  • 代码演示
    NSArray *anNSArray = @[@1,@2,@3,@4,@5];
    CFArrayRef aCFArray = (__bridge CFArrayRef)anNSArray;
    NSLog(@"Size of array = %li",CFArrayGetCount(aCFArray));
    //Output: Size of array = 5
__bridge 保留ARC所有权
__bridge_retained 交出ARC所有权
__bridge_transfer CF对象转OC对象所有权交给ARC
  • 例如使用CFMutableDictionary创建出保留key的Dictionary

第48条 多用块枚举,少用for循环

  • Objective-C 1.0反向枚举器
NSArray *anArray = /* ... */;
NSEnumerator *enumerator = [anArray reverseObjectEnumerator];
id object;
while((object = [enumerator nextObject]) != nil) {
     //do something with 'object'
}
  • 快速遍历
NSArray *anArray = /*...*/;
for (id object in anArray) {
    //do something with 'object'
}
  • 自定义快速遍历需要�NSFastEnumeration协议
//实现协议方法
- (NSUInteger) countByEnumeratingWithState:(NSFastEnumerationState*)state
                                   objects:(id*)stackbuffer
                                   count:(NSUInteger)length
  • Objective-C 2.0快速反向遍历

    缺点:拿不到下标
NSArray *anArray = /*...*/;
for (id object in [anArray reverseObjectEnumerator]) {
     //do something with 'object'
}
  • 基于块的遍历方式
NSArray *anArray = /*...*/;
[anArray enumerateObjectsUsingBlock:
    ^(id object, NSUInteger idx, BOOL *stop){
        //do something with 'object'
        if(shouldStop) {
            *stop = YES;
        }
    }];
  • 可以使用NSEnumerationOptions类型

    NSEnumerationReverse 反向遍历

    NSEnumerationConcurrent 并发遍历

第47条 熟悉系统框架

NSLinguisticTagger 解析字符串并找到其中的全部名词,动词,代词
CFNetwork C语言网络通信框架
CoreAudio C语言Api操作设备伤的音频硬件框架
AVFoundation 回放并录制音频视频
CoreData Objective-C对象持久化框架
CoreText C语言接口文字排版及渲染

第46条 不要使用 dispatch_get_current_queue

  • 该函数用来获取当前的队列,已经标记废弃。
  • 使用dispatch_get_current_queue依然会死锁的例子
dispatch_sync(queueA, ^{
    dispatch_sync(queueB,^{
        dispatch_block_t block = ^{/*....*/};
        if(dispatch_get_current_queue() == queueA) {
            block();
        } else {
            dispatch_sync(queueA, block);
        }
    });
});
//解决方法,使用dispatch_get_specific来替换上面这种写法
  • GCD派发层级
            全局并发队列
                /    \
        串行队列A   串行队列D
         /    \
   串行队列A    串行队列D
串行队列B,C的任务有可能放到队列A中交替执行
串行队列A,D的目标是并发队列,A,D中的块会并发执行

相关文章

网友评论

      本文标题:Effective Objective-C 2.0 笔记

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