您的位置:首页 > 移动开发 > IOS开发

IOS学习笔记(12)——一个模态视图切换bug引发的思考

2014-10-08 17:33 501 查看
1、开发场景

最痛苦的不过是在别人留下的一堆代码中修复bug。最近工程项目需要修复一个困扰已久的bug,这个虽然是一个页面的闪过问题,不会影响功能,

只是看起来有点不舒服。最早开发的前辈们都已经不在了,但是如果修改它,就会牵一发而动全身,需要修改的东西太多了。要知道,没有人敢轻易

去动原有已经成熟稳定的东西。这个由于模态视图切换引起的bug,我最近狠了心,决定去修复它。

问题大致是这样子的:



2、以下是前辈们留下的代码逻辑:

有个管理的主界面。有众多的入口要进入这个界面,当然进入这个界面之前需要先调用管理主界面的checkLogin方法进行登录判断,如果已经登录则

直接push进入主界面。否则,仍需要push主界面,再视图模态切换到登录界面,待登录成功以后,信息回传将登录试图模态“踢出”直接显示主界面。

入口处代码如下:

ManagerViewController * t = [[ClassFactory instance]createSingletonController:@"ManagerViewController" param:nil];
[[AppController instance] pushController:t];
[t checkLogin];


3、于是问题来了:

当你未登录进入管理主界面时,会先出现没有任何信息的管理主界面再进入登录界面,这个过程中间会出现“闪过”管理界面的现象,

这不会影响到功能,但是作为对用户体验要求很高的移动产品来说,很明显这是一个很糟糕的设计。

4、可能会有人疑问:

为何不在主界面入口的controller界面进行判断呢?我也有过这样的疑问,后来研究发现,前辈们把checkLogin方法写在管理主界面的controller里面也是有一定道理的。

毕竟入口有可能会很多,在很多处进行checkLogin判断,很明显这也不是很好的设计。

5、我的修改方案

修改方案一:

当初发现这个问题是,第一反应就是用performSelector:方法来解决。原来的代码逻辑几乎不动,直接将push主界面实例这一操作,延迟执行不就行了吗。不得不承认,

我很喜欢用performSelector:这个方法,因为它在解决这种push界面的顺序问题,很好使。 但是它在我们这个偌大的工程中使用,有个很要命的缺点,就是会经常执行后

卡死界面。没办法,尽管好使,不得不丢弃这个方案。代码如下:

修改方案二:

修改这种问题有个潜规则,就是尽可能小的改动源代码,不然你可能带来很多其它潜在的bug。我的修复方案是这样子的:在入口controller界面要进入管理主界面时,

(1) 实例化管理主界面类,调用checkLogin方法,如果已经登录,直接push管理主界面的实例;

(2) 实例化管理主界面类,调用checkLogin方法,如果未登录,模态切换到登录试图进行登录,并将管理主界面controller实例传给登录界面,待登录成功后,再将管理主界面实例push入栈;

大致的代码实现如下:

入口处代码如下:

ManagerViewController * t = [[ClassFactory instance]createSingletonController:@"ManagerViewController" param:nil];
if (![t checkLogin])
{
[[AppController instance] pushController:t];
}


登录controller里面:

if (isLogin)
{
/* 登录成功后,先将tManagerViewController压入堆栈,为主界面显示做准备;
[[AppController instance] pushController:self.tManagerViewController];
.....
}


checkLogin方法大致如下:

- (bool)checkLogin
{
if (....)
{
LoginViewController * wLoginController = [[LoginViewController alloc] init];
wLoginController.tManagerViewController = self;
....
return true;
}
return false;
}


6、此修改引入的bug

尽管这个修改很保守,但是仍旧被测试测出了很多bug,原因很简单,修改引入了很多其他问题,下面举典型的如下:

(1) 管理主界面有个自动登出的功能,就是过了大约5分钟后,管理界面会自动退出。原来的自动退出里面只是切换到了登录界面,没有将管理界面pop出来。这样的话,如果自动登出后,再次登录进入管理主界面,栈里会有两个管理主界面的ManagerViewController了,此时主界面会”卡死“;按照方案二修改后,退出操作里面需要再次将管理主界面pop出来。

7、参考资料

《iOS开发指南》——关东升
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: