68

iOS 编写高质量Objective-C代码(八)

 5 years ago
source link: http://www.cocoachina.com/ios/20181207/25755.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言:

这几篇文章是小编在钻研《Effective Objective-C 2.0》的知识产出,其中包含作者和小编的观点,以及小编整理的一些demo。希望能帮助大家以简洁的文字快速领悟原作者的精华。

在这里,QiShare团队向原作者Matt Galloway表达诚挚的敬意。

文章目录如下:

本篇的主题是:“系统框架”。

在我们日常开发中,都会使用系统的一些框架。因此熟悉系统框架是很有必要的。

那么今天,我们就一起来探索一下系统框架中有哪些珍宝呢?

一、熟悉系统框架

系统框架包括但不限于:

  • 1. Foundation:基础框架。

提供了包括数据存储和持久性,文本处理,日期和时间计算,排序和过滤以及网络等功能。Foundation定义的类,协议和数据类型在整个macOS,iOS,watchOS和tvOS SDK中使用。

  • 2. CoreFoundation:核心基础框架。

提供了C语言级的基础功能,为应用程序提供基本数据管理和服务功能。并可通过无缝桥接技术(__bridge)实现C语言类与OC对象的转换。

  • 3. UIKit:视图框架。

为iOS与tvOS提供界面与视图的功能。(重要:除非另有说明,否则一定要在主线程中使用UIKit框架。)

  • 4. CoreAnimation:核心动画框架。

提供了高帧速率和流畅的动画功能,并且不会给CPU太多负担,也不会降低应用程序的响应速度。

  • 5. CoreGraphics:核心图形框架。

基于Quartz绘图引擎,提供了轻量级2D渲染所必备的数据结构与函数。包括CGPoint、CGSize、CGRect等数据结构。

  • 6. CoreData:核心数据框架。

提供了将OC对象写入数据库的功能,便于持久保存。

  • 7. CoreText:文本框架。

提供了C语言级别的文字排版及渲染操作。

  • 8. AVFoundation:音视频框架。

提供了控制摄像头,以及处理、合成、控制、导入、导出音频/视频的功能。

  • 9. CFNetwork:网络框架。

提供了C语言级别的网络通信能力,将BSD socket抽象成易于使用的网络接口,以便网络通信。

  • 10. ARKit:AR框架。

  • 11. SpriteKit:2D游戏框架。

  • 12. CoreLocation、MapKit:定位地图相关框架。

  • 13. Address Book:通讯录框架。

  • 14. HealthKit:健康相关框架。

  • 15. HomeKit:为智能化硬件提供的框架。

  • 16. PhotoKit:相册框架。

......(还有很多框架,详细的请看下面的官方文档。)

PS:苹果官方文档

二、多用块枚举,少用for循环

遍历collection有四种方法:for循环、NSEnumerator遍历法、for-in快速遍历法、块枚举法。

1. for循环:

最基本的循环方法,与其他语言类似。

NSArray *arr = @[@1, @2, @3, @4, @5];

for (NSInteger i = 0; i < 5; i++) {
    NSLog(@"%@",arr[i]);
}

2. NSEnumerator遍历法:

NSArray *arr = @[@1, @2, @3, @4, @5];

NSEnumerator *enumerator = [arr objectEnumerator];
NSNumber *num = nil;

while ((num = [enumerator nextObject]) != nil) {
    NSLog(@"%@",num);
}

3. for-in快速遍历法:

在开发中,常使用的方法。

NSArray *arr = @[@1, @2, @3, @4, @5];

for (NSNumber *num in arr) {
    NSLog(@"%@",num);
}

4. 块枚举法:

基于块来遍历,遍历时既能获取对象,也能知道其下标。此外,还能通过stop对象终止遍历。(即调用*stop = YES即可)

  • 官方:Executes a given block using each object in the array, starting with the first object and continuing through the array to the last object.

  • 翻译:使用数组中的每个对象执行给定的block,从第一个对象开始,一直到最后一个对象。

  • 基本使用:

NSArray *arr = @[@1, @2, @3, @4, @5];

[arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    NSLog(@"%@",obj);

    if (idx == arr.count - 1) {
        *stop = YES;
    }
}];

三、对自定义其内存管理语义的collection使用无缝桥接

无线桥接技术(__bridge):可将“ OC对象 ”与“ C语言中的数据结构 ”来回转换。

举个简单的例子:NSArray与CFArrayRef的无缝桥接。

NSArray *anNSArray = @[@1, @2, @3, @4, @5];

CFArrayRef aCFArray = (__bridge CFArrayRef)anNSArray;//!< 无缝桥接
NSLog(@"Size of array = %li", CFArrayGetCount(aCFArray));
// Output: Size of array = 5

四、构建缓存时选用NSCache而非NSDictionary

NSCache的优点:

  • 当系统资源将要耗尽时,NSCache会自动删减。并先行删除“最久未使用的对象”。

  • NSCache不会自动拷贝键。(PS:因为NSCache没有遵循 / 协议)

  • NSCache是线程安全的。在不加同步锁的前提下,依然支持多线程访问NSCache。

五、精简load与initialize的实现代码

load与initialize方法都要保持精简。

load中的注意点:

  1. 如果分类和所属类都定义了load方法,则会先调用主类里的load方法,然后再调用分类的。

  2. 在load方法内使用其他类是不安全的。(因为调用时其他类可能还没有加载好)

  3. 如果某个类本身没有实现load方法,那么不管超类是否实现load方法都不会调用。

  4. load应只用于调试,而非执行任务。

initialize中的注意点:

  1. 如果某个类未实现initialize,而其超类实现了,就会运行超类的方法。

  2. 开发者无法控制类的初始化时机。

  3. 如果某个类的initizalize实现代码很复杂,其中用到了别的类。若那些类还没初始化,就会强迫他们初始化。

  4. initialize方法只应该用来设置内部数据。

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

  • NSTimer对象会保留其目标,直到计时器本身失效为止,调用[_timer invalidate];可令计时器失效。另外,一次性的计时器在触发完任务后也会失效。

  • 反复执行任务的计时器(repeating timer)很容易产生循环引用。如果这种计时器的目标对象又保留了计时器本身,那就会产生循环引用,导致内存泄漏。可能是直接发生的,也可能是其他对象间接发生的。

作者: MrLiuQ

审校: QiShare团队

链接:https://www.jianshu.com/p/9ef6467ed06f


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK