iOS应用页面重载时出现异常行为的技术问询
首先得先纠正一个常见的误解:viewDidLoad 并不是每次页面返回都会触发的,它只会在视图控制器的视图第一次加载完成时执行一次。如果你的页面是通过push进入导航栈,再pop回来,控制器并不会被销毁,所以viewDidLoad不会再次调用;只有当控制器被系统回收(比如内存警告)或者你手动销毁后,再次初始化才会重新执行。你感觉到的“每次加载视图”更可能是viewWillAppear:或viewDidAppear:方法在触发。
结合你描述的现象——调用update_schedule:后返回页面值自动递增,我整理了几个最可能的原因和对应的解决方案:
一、实例变量未正确重置
如果存储filteredArray或相关数据的是ViewController的实例变量,且你没有在每次获取新数据前重置它,就可能导致旧数据和新数据叠加,或者逻辑上错误地累加了值。比如调用update_schedule:后,后端数据更新了,但旧的本地数组没清空,下次获取时出现了异常的数值计算。
解决方案:
- 在
get_shcedule方法开头先重置存储数组的变量,确保每次都是全新的结果:// 假设_filteredArray是你的实例变量 _filteredArray = nil; NSArray *filteredArray = [[jsonArray filteredArrayUsingPredicate:predicate] valueForKey:@"hour"]; _filteredArray = filteredArray; - 把获取数据的逻辑从
viewDidLoad移到viewWillAppear:里,确保每次页面显示时都拉取最新数据,而不是只在控制器初始化时获取一次。
二、array2的生命周期问题
array2作为实例变量,如果在update_schedule:里初始化时没有先清空旧数据,可能导致旧的更新值残留,后续被错误地用到get_shcedule的逻辑中,引发数值递增。
解决方案:
- 在初始化
array2前先清空原有内容,或者直接重新赋值(ARC会自动处理旧引用):// 方式1:清空旧数据再初始化 [array2 removeAllObjects]; array2 = [[NSMutableArray alloc] init]; // 方式2:直接创建新数组,更简洁 array2 = [NSMutableArray array]; - 检查
get_shcedule方法里是否有任何地方意外用到了array2的数据,如果有,确保只在必要场景使用,且每次获取新数据时不依赖旧的array2值。
三、后端返回数据异常
有可能你的update_schedule:请求发送后,后端逻辑存在问题——比如没有正确处理更新请求,反而每次查询都自动把数值加1。这种情况下,本地代码逻辑没问题,问题出在服务端。
解决方案:
- 在
get_shcedule方法里打印原始的jsonArray数据,确认后端返回的数值是否已经是递增后的:
如果打印出的原始数据已经是递增状态,那就要和后端同学配合调整服务端的逻辑了。NSLog(@"原始接口返回数据:%@", jsonArray); NSArray *filteredArray = [[jsonArray filteredArrayUsingPredicate:predicate] valueForKey:@"hour"]; NSLog(@"过滤后的hour数组:%@", filteredArray);
四、视图控制器被重复创建
如果你在返回页面时没有复用原有控制器实例,而是每次都新建一个ViewController,同时数据存储用了全局变量或单例,就可能导致新实例获取到旧实例更新后的数据,进而出现数值递增的情况。
解决方案:
- 检查页面跳转逻辑:如果是用push/pop或present/dismiss的方式,返回时默认就是复用原有控制器实例;如果是手动创建新实例跳转,要改成复用旧实例,或者确保全局存储的数据在每次控制器初始化时被重置。
快速排查步骤
- 先在
viewDidLoad里加日志,确认它是否真的每次返回都被调用:NSLog(@"viewDidLoad 触发"); - 打印接口返回的原始数据和过滤后的数组,区分是本地还是后端问题
- 检查所有相关实例变量的初始化、重置逻辑,确保没有旧数据残留
- 确认
array2的使用范围,避免它干扰get_shcedule的数据获取逻辑
内容的提问来源于stack exchange,提问作者humble_pie

