加载文件后如何检测未初始化的NSMutableArray?
检测未初始化NSMutableArray的方案
针对你遇到的未初始化可变数组问题,这里提供几种实用的检测方法,帮你在遍历前识别并处理无效对象:
类型检查+异常捕获组合验证
未初始化的对象不是nil,也不是合法的NSMutableArray实例,甚至可能伪装成数组类型。可以先做类型判断,再通过@try/@catch捕获调用方法时的异常,确保对象能正常工作:// 遍历数组1时检测每个元素 NSMutableArray *array1 = ...; // 从文件加载的数组 NSMutableIndexSet *invalidIndexes = [NSMutableIndexSet indexSet]; [array1 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // 先判断是否是可变数组类型 if (![obj isKindOfClass:[NSMutableArray class]]) { [invalidIndexes addIndex:idx]; return; } // 尝试调用count方法,验证对象是否初始化完成 @try { [obj count]; } @catch (NSException *exception) { [invalidIndexes addIndex:idx]; } }]; // 批量移除无效对象 [array1 removeObjectsAtIndexes:invalidIndexes];CoreFoundation类型ID底层校验
利用CoreFoundation的稳定类型ID来判断对象是否为合法数组,这种方式比OC的类型判断更底层,能规避isa指针被篡改的情况:id obj = ...; // 待检测的数组2 if (CFGetTypeID((__bridge CFTypeRef)obj) != CFArrayGetTypeID()) { // 不是合法的数组对象,执行移除或跳过逻辑 [array1 removeObject:obj]; }注:
NSMutableArray是NSArray的子类,对应的CF类型ID和NSArray一致,所以用CFArrayGetTypeID即可验证。加载阶段提前过滤
与其加载后再处理,不如在从文件加载对象时就做安全校验,直接过滤掉无效对象:// 以NSKeyedUnarchiver加载为例 id loadedData = [NSKeyedUnarchiver unarchiveObjectWithFile:@"yourFilePath"]; if ([loadedData isKindOfClass:[NSMutableArray class]]) { NSMutableArray *validArray = [NSMutableArray array]; for (id item in (NSMutableArray *)loadedData) { // 验证是数组且能正常调用方法 if ([item isKindOfClass:[NSMutableArray class]]) { @try { [item count]; [validArray addObject:item]; } @catch (NSException *e) { continue; } } } // 后续业务逻辑使用validArray }
补充说明:未初始化的对象本质是内存中的垃圾数据,它的isa指针可能指向错误的类,所以单纯的类型判断可能存在误判,结合异常捕获是最稳妥的方式——调用未初始化对象的方法会直接抛出NSInvalidArgumentException(也就是你遇到的-[NSMutableArray count]: method sent to an uninitialized mutable array object错误)。
内容的提问来源于stack exchange,提问作者Carl Carlson
相关产品推荐
相关产品推荐

