表现:app崩溃或者卡死,直接卡到必须关机重启才行,最终在腾讯的bugly被记录下来,但是也不好定位问题,一脸懵。
好像会 #1018848 SIGABRT xxxASK + 92216 解决方案 abort program SIG是信号名的通用前缀。ABRT是abort program的缩写。 当操作系统发现不安全的情况时,它能够对这种情况进行更多的控制,必要的话,它能要求进程进行清理工作。在调试造成此信号的底层错误时,并没有什么妙招。 如 cocos2d 或 UIKit 等框架通常会在特定的前提条件没有满足或一些糟糕的情况出现时调用 C 函数 abort (由它来发送此信号)。 如果是iOS系统: 发生在UIApplication WillTerminate 时,是主动退出应用时发生的,所以对用户没什么实际影响。 iOS10访问相册时发生,目前只发生在iOS10+系统,需要修改工程plist文件,加入访问权限提示信息。 补充:iOS 10 has updated privacy policy and implemented new privacy rules. You have to update your Info.plist app with this following fields by authorisation asked.
static (extension in Foundation):Swift.Dictionary. unconditionallyBridgeFromobje ctiveC( C.NSDictionary?)->[A:B]+ 320
shared preferences foundation $s29shared preferences foundation23SharedPreferencesPlugincllgetAllPrefs9allowList7optionssDysSypGsayssGSg_AA0dE13PigeonoptionsVtKFZ + 408
如上图:感觉某个字典出现了问题,但是也没法定位问题。
一次偶然的问题,再测试那复现了,调试了一上午,他的是iPhone11 iOS18.2.1,版本系统比较新,我的是18.0和18.1.1就没有出现,难道是apple的最新系统才出现问题? 搞了一上午,一点点定位代码,最终找到了出现在很久以前写的代码:
[[NSUserDefaults standardUserDefaults] setObject:brUid forKey:brUid]; 这里出现了问题,key和value不可以一样, key最好是字符串类型,这里不仅key和value一样了,而且通过deepseek了解到,若是key类型不确定,比如number类型或者nil类型话也会崩溃。
如下是ai给出的结果:
使用 [[NSUserDefaults standardUserDefaults] setObject:brUid forKey:brUid];
存在以下问题:
1. Key-Value 设计不合理
-
Key 与 Value 相同:将动态变量
brUid
同时作为 Key 和 Value,会导致存储逻辑混乱。Key 应是固定字符串标识符,而 Value 应为需持久化的动态值。这种写法可能导致:- 无法通过固定 Key 读取数据,后续无法正确检索存储的值12。
- 若
brUid
是动态值(如用户 ID),每次存储会生成不同的 Key,导致存储冗余数据且无法有效管理34。
2. 数据类型不匹配
- NSUserDefaults 仅支持基础类型(如
NSString
、NSNumber
、NSData
、NSDate
、NSArray
、NSDictionary
)。若brUid
是自定义对象或不符合上述类型,直接存储会引发崩溃。需确保值对象是可序列化类型,否则需归档为NSData
34。
3. 潜在的空值崩溃
- 若
brUid
为nil
,setObject:forKey:
方法传入nil
时会触发异常(NSInvalidArgumentException
)。应在存储前判空,或改用removeObjectForKey:
移除 Key3。
4. 线程安全问题
- NSUserDefaults 虽然是线程安全的,但在多线程环境下频繁读写可能导致数据覆盖或读取不一致。建议在单一线程中操作或通过
@synchronized
同步代码块保证原子性36。
5. 存储域污染
- 默认存储域(Application Domain)中动态生成的 Key 会污染持久化数据,增加维护难度。应通过固定 Key 隔离不同用途的数据(如
@"userID"
)24。
6. 数据同步延迟
- 未显式调用
synchronize
方法时,数据可能不会立即写入磁盘,极端情况下可能导致数据丢失(尽管现代系统已优化自动同步逻辑,但关键操作仍建议调用该方法)12。
改进建议
objective-cCopy Code
// 1. 使用固定 Key
static NSString *const kBRUIDKey = @"BRUIDKey";
// 2. 存储前检查数据类型及空值
if (brUid && [brUid isKindOfClass:[NSString class]]) {
[[NSUserDefaults standardUserDefaults] setObject:brUid forKey:kBRUIDKey];
[[NSUserDefaults standardUserDefaults] synchronize]; // 必要时强制同步
} else {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kBRUIDKey];
}
其他注意事项
- 跨应用数据共享:若需通过 App Groups 共享数据,应使用
initWithSuiteName:
初始化实例5。 - 不可变对象:NSUserDefaults 存储的数组、字典等对象均为不可变类型,需通过
mutableCopy
获取可变副本4。