系统框架

Saturday, February 24, 2018

熟悉系统框架

  • 除了常见的 Foundation 框架和 CoreFoundation 框架,还有如下几个框架

    • CFNetWork 此框架提供了 C 语言级别的网络通信能力,它将 BSD 套接字抽象成易于使用的网络接口。
    • CoreAudio 此框架提供 C 语言API 来操作设备上的音频硬件。
    • AVFoundation 此框架所提供的 Objective-C 对象可用来回放并录制音频及视频。
    • CoreData 将对象持久化至数据库中。
    • CoreText 此框架提供 C 语言接口高效执行文字排版及渲染操作。
    • CoreGraphics 框架提供了2D 渲染所必备的数据结构与函数。

多用块枚举,少用 for 循环

  • 快速遍历:for in

  • 若要反向遍历数组,则:

    for (id object in [array reverseObjectEnumerator]) { //Do something }

  • 基于块的遍历方式:既能获取到对象和 key,也能知道其下标,还提供了一种机制用于终止边里操作,用此方式也可以执行反向遍历。

    //遍历数组 [anArray enumerateObjectsUsingBlock: ^(id object, NSUInteger idx, BOOL *stop) { if (shouldStop) { *stop = YES; } }];

    //遍历字典与 set [aDictionary enumerateKeysAndObjectsUsingBlock: ^(id key, id object, BOOL *stop) { if (shouldStop) { *stop = YES; } }];

    [aSet enumerateObjectsUsingBlock: ^(id object, BOOL *stop) { if (shouldStop) { *stop = YES; } }];

构建缓存时选用 NSCache 而非 NSDictionary

  • NSCache 胜过 NSDictionary 的地方在于,当系统资源将要耗尽时,会自动删减缓存,而且还会先行删减最久未使用的对象。

  • NSCache 不会拷贝键,而是保留它。

  • NSCache 是线程安全的

    typedef void(^EOCNetworkFetcherCompletionHandler)(NSData *data); @interface EOCNetworkFetcher: NSObject

    • (id)initWithURL:(NSURL *)url;
    • (void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler; @end

    @interface EOCClass: NSObject @end

    @implementation EOCClass { NSCache *_cache; }

    • (id)init { if ((self = [super init])) { _cache = [NSCache new]; _cache.countLimit = 100; _cache.totalCostLimit = 5 * 1024 * 1024; } return self; }

    • (void)downloadDataForURL:(NSURL *)url { NSData *cacheData = [_cache objectForKey: url]; if (cacheData) { [self useData:cachedData]; }else { //没有缓存 EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL: url]; [fetcher startWithCompletionHandler: ^(NSData *data) { [_cache setObject:data forKey:url cost:data.length]; [self useData:data]; }]; } } @end

精简 initialize 与 load 的实现代码

<code class="language-null">+ (void)load
</code>
  • 对于加入运行期系统中的每个类及分类,必定会调用此方法,而且只调用一次。

  • 在 load 中无法判断出各个类的载入顺序,因此在 load 中使用其他类是不安全的。

  • load 方法并不遵从那套继承规则。

  • load 方法尽量减少其所执行的操作,整个应用程序在执行 load 方法时都会阻塞。

  • load 方法的真正用途仅在于调试程序,比如可以再分类里编写此方法,用阿里判断该分类是否已经正确载入系统。

    + (void)initialize

  • 它是惰性调用的,只有程序用到相关的类时,才会调用。

  • initialize 方法与其他消息一样,如果某个类未实现它,而超类实现了,那么就会运行超类的实现代码。

  • 只应该用来设置内部数据,不应该在其中调用其他方法,即便是本类的方法,也别调用。

  • 无法再编译期设定的全局常量,可以放在 initialize 方法里初始化。

别忘了 NSTimer 会保留其目标对象

  • NSTimer 对象会保留其目标,直到计时器本身失效为止,调用 invalidate 方法可以令计时器失效,一次性的计时器在触发完任务之后也会失效。
  • 反复执行任务的计时器,很容易引入保留环,如果这种计时器的目标对象又保留了计时器本身,就会导致保留环。
iOSObjective-C

GCD详解

Block与GCD要点