一、管理
1、规范代码管理
2、搭建项目框架,制定代码规范
3、制订接口文档规范
4、统一封装满足多样化网络请求的网络库基础接口
5、组件的解耦封装
6、在当前工程中导入另一个工程文件
可扩展性:构建可扩展的iOS应用架构
稳定性治理:监控和分析崩溃日志来识别和修复潜在的问题。内存泄露。
iOS应用的稳定性可以通过多种方式来提升。首先,通过监控和分析崩溃日志来识别和修复潜在的问题。其次,通过优化代码和内存管理来减少卡死和崩溃的发生。例如,避免死锁、线程饥饿和内存泄漏等问题。此外,使用性能监控工具来检测应用的性能瓶颈,如卡顿和延迟,也是提高稳定性的重要手段。
灵活性:面向协议编程
二、风险预测
1、风险可能
1、不要过分相信服务器返回的数据会永远的正确。
2、在对数据处理上,要进行容错处理,进行相应判断之后再处理数据,这是一个良好的编程习惯。
2、思考:如何防止存在潜在崩溃方法的崩溃
- 众所周知,Foundation框架里有非常多常用的方法有导致崩溃的潜在危险。对于一个已经将近竣工的项目,若起初没做容错处理又该怎么办?你总不会一行行代码去排查有没有做容错处理吧!——– 别逗逼了,老板催你明天就要上线了!
- 那有没有一种一劳永逸的方法?无需动原本的代码就可以解决潜在崩溃的问题呢?
3、解决方案
解决方案:拦截存在潜在崩溃危险的方法,在拦截的方法里进行相应的处理,就可以防止方法的崩溃
步骤:
1 2 3
| 1、通过category给类添加方法用来替换掉原本存在潜在崩溃的方法。 2、利用runtime方法交换技术,将系统方法替换成我们给类添加的新方法。 3、利用异常的捕获来防止程序的崩溃,并且进行相应的处理。
|
4、消息转发机制
iOS的消息转发机制详解
5、消息转发机制的运用
1、简单问题引导
用Runtime解决服务器返回NSNull问题
思路:重写NSNull的消息转发方法, 让他能处理这些异常的方法.
使用 Method Swizzling 交换 objectForKey: 和 objectAtIndex: 是 方法交换(Method Swizzling),并不是 消息转发机制(Message Forwarding)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| ✅ 使用 Runtime 交换方法,拦截 NSNull,避免手动检查 ✅ 提升代码健壮性,防止 NSNull 访问崩溃 ✅ 适用于 NSDictionary 和 NSArray,避免手动 if ([obj isKindOfClass:[NSNull class]]) #import <objc/runtime.h>
@implementation NSDictionary (Safe)
+ (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethod = class_getInstanceMethod(self, @selector(objectForKey:)); Method swizzledMethod = class_getInstanceMethod(self, @selector(safe_objectForKey:)); method_exchangeImplementations(originalMethod, swizzledMethod); }); }
- (id)safe_objectForKey:(id)key { id value = [self safe_objectForKey:key]; if ([value isKindOfClass:[NSNull class]]) { return nil; } return value; }
@end @implementation NSArray (Safe)
+ (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethod = class_getInstanceMethod(self, @selector(objectAtIndex:)); Method swizzledMethod = class_getInstanceMethod(self, @selector(safe_objectAtIndex:)); method_exchangeImplementations(originalMethod, swizzledMethod); }); }
- (id)safe_objectAtIndex:(NSUInteger)index { if (index >= self.count) { return nil; } id value = [self safe_objectAtIndex:index]; if ([value isKindOfClass:[NSNull class]]) { return nil; } return value; }
@end
|
🔥 使用消息转发机制(Message Forwarding)解决 NSNull 问题
🔹 原理
1. 当访问 NSNull 的方法时,系统先在 NSNull 查找对应的方法
2. 如果 NSNull 没有该方法,会触发消息转发流程
3. 重写 forwardingTargetForSelector: 或 methodSignatureForSelector: + forwardInvocation: 来拦截并提供安全返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| NSNull *nullValue = [NSNull null];
NSLog(@"Length: %lu", (unsigned long)[nullValue length]);
NSLog(@"Integer: %ld", (long)[nullValue integerValue]);
✅ 方案 1:使用 forwardingTargetForSelector:(快速消息转发),返回要让哪个tagert去执行aSelector方法。 #import <Foundation/Foundation.h>
@interface NSNull (SafeForwarding) @end
@implementation NSNull (SafeForwarding)
- (id)forwardingTargetForSelector:(SEL)aSelector { NSLog(@"⚠️ NSNull 被调用方法: %@", NSStringFromSelector(aSelector)); static NSString *emptyString = @""; static NSNumber *zeroNumber = @0; if ([emptyString respondsToSelector:aSelector]) { return emptyString; } else if ([zeroNumber respondsToSelector:aSelector]) { return zeroNumber; } return nil; }
@end
✅ 方案 2:完全转发,略
假设 NSString 有这样一个方法: - (NSUInteger)length; 它的 方法签名 大致如下: NSMethodSignature *sig = [NSString instanceMethodSignatureForSelector:@selector(length)];
|
防止Crash 组件
2、系统性解决:
iOS runtime实用篇 —避免常见崩溃
其中AvoidCrash的代码如下:AvoidCrash源代码
附:NSException
iOS被开发者遗忘在角落的NSException-其实它很强大
利用OC的消息转发机制实现多重代理
三、资源
app瘦身
四、代码
1、单元测试
单元测试分为3种:
1 2 3
| 逻辑测试:测试逻辑方法 异步测试:测试耗时方法(用来测试包含多线程的方法) 性能测试:测试某一方法运行所消耗的时间
|
为什么要使用单元测试:
1 2 3
| 经济上的问题:
假设要开发的是对接获取验证码接口的方法,难道运行一次就真的请求一个短信验证码?短信下发平台可是会¥扣钱¥的。更何况,万一第三方平台没有响应或超时,我们的测试就失败了,这种异步的、不确定的测试,无论从金钱还是时间上衡量,都不够经济,因此很难实现。
|
什么情况下时序使用单元测试(单元测试使用的注意事项):
1 2 3 4 5 6
| 1、不是所有的方法都需要测试。 例如:私有方法不需要测试!只有暴露在 .h 中的方法需要测试!面向对象有一个原则:开闭原则! 2、所有跟 UI 有关的都不需要测试,也不好测试。 把 业务逻辑 代码封装出来!变成可以测试的代码,让程序更加健壮! 3、一般而言,代码的覆盖度大概在 50% ~ 70% 从github上得知:YYModel测试覆盖度为83%,AFNetworking测试覆盖度为77%,两者都是比较高的。
|
2、优化多线程处理,改善多线程嵌套严重,请求耗时的问题
解决:优化多线程处理,改善多线程嵌套严重,请求耗时的问题。
详细:原本项目,采用多线程嵌套的同步方式处理多个线程请求到数据后,再执行最后操作。经优化多线程处理为异步执行时,改善了多线程嵌套严重,请求耗时的问题。
3、定时器使用的优化
4、UITableView等的性能优化
5、优化代码逻辑处理(耗电量、耗流量)
性能优化