美文网首页
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