最近在阅读大神Casa Taloyum
的博客,发现他不仅文章写得好,还尽心尽力的回复每一个人的评论,每篇文章评价都上百条,一条条看下来,受益匪浅,不仅有初学者的问题,也有开发遇到瓶颈的探讨,作者都一一解答,我就摘抄了一部分,让大家分享。
1、什么时候添加和删除notification
?
答:
- 根据最小权力原则,我们倾向于优先放在展示周期去监听事件。
ViewController
的展示周期是小于ViewController
的生命周期的,所以一般如果能在展示周期完成的监听事件的需求,就不会放到生命周期中去做。除非展示周期搞不定的,才会把监听扩大到生命周期。
2、如果一个ViewController
有很多的业务,视图也比较复杂,该怎么拆分呢?我想把业务的处理和页面跳转抽取出来,放到一个category
里面,这样viewController
可以减少很多代码,但是这个category
貌似没有复用的价值。
另外,如果UITableView
里面有很多不一样的cell
,如何重构代码才能使cell
的逻辑简化呢?我尝试用工厂模式去解决,但是发现每个cell
需要的model
参数都差不多,无法通过model
去区分,而通过indexPath
去区分的话又不方便重用,只能是一个页面适用。
答:
-
一般是按照业务角色来拆分业务模块,这需要你对业务有很好的抽象能力。首先,用
Category
来做对象功能拆分这个思路是没错的,但是对于拆分ViewController
来说,拆分更加偏重的是对业务的抽象,然后设立角色,这样才能做到可复用,所以category
的思路在这种场景下是不适用的。category
只是把大对象变多个小对象而已,它适合拆分那种本身就已经抽象程度比较高、可复用性比较高的底层对象,而不适合用来拆分业务。 -
独立出
DataSource
成一个对象,DataSource
事实上就可以理解为一个factory
,然后DataSource
根据Controller
给的指示(通过设置DataSource
属性也好,通过方法穿参数也行)去生产当前需要的Cell
3、在模块化开发时,模块开发完。我们还需要一个入口工程,一般是UITabBarController
。在这个入口工程里,在用户退出后,要如何刷新UITabBarItem
对应的页面呢?目前我想到的有两种,一种是我重新创建UITabBarController
,具体做法就是,当退出时,将LoginViewController
切换rootViewController
,如果登录成功后,再切换成UITabBarController
为rootViewController
.第二种方式,是登录页面使用模态方式显示(我看淘宝目前是这样处理的),退出登录时,抛退出登录的通知,让每个TabbarItem
页面刷新。因为我们现在有个游客访问的功能,所以如果使用第一种切换rootViewController
的方式,就会频繁创建释放ViewController
,我不确定这样是否会有问题?而且我点击某个按钮弹出登录提示框后,去登录,如果登录成功后,就会显示首页而不是直接进入之前点击想进入的页面。如果使用第二种方式,抛通知,每个页面都处理这个通知,这样是否是好的方式?而且这里的通知处理还有特殊处理,因为刷新的页面如果有异常,这个时候不能弹出提示,否则就会在显示登录页面上弹出异常提示会很奇怪。
答:
- 你的这种场合我还是建议抛通知,但是抛通知之后,只有当前正在展示的
viewcontroller
才刷新,其他viewcontroller
收到通知后记录下状态,在viewdidappea
r的时候再刷新。
4、请问如何处理token
过期后从任意controller
跳回登陆界面的情况?我现在有几个api用到了token,那么就会存在token过期的情况,当token
过期时,需要跳回登陆界面重新登陆。我在调api时服务器会在response
的header
里返回401
,我现在是在每个需要调api的controller里都监听通知,如果api返回了401,就post通知,然后收到通知的controller就pop回root,我知道这样做不太好,所以想请教有没有更好的解决方案。
答:
-
前半部分没错,遇到token失效就扔个
Notification
出去。但是接收
Notification
的人不是ViewControlle
r。你应该有一个中间人接收这个Notification
,而且你的Notification
的object
是当前正在发起请求失败的这个APIManager
。具体流程应该是这样:
XAPIManager
请求失败(token失效,且在BaseApiManager
中判断)后,扔出通知,将通知的object
设为当前失败的这个Manager
也就是XManager
。然后中间人收到通知,记录下随着
Notification
过来的Object
,也就是失败的那个Manager
。然后在当前ViewController
中present
登陆页面。嗯,你是有方法能够在外面知道当前正在展示的ViewController
的,具体方法你可以去Google。后面就是让用户登录了。中间人收到
Token
刷新成功的回调,拿出刚才拿到的失败的那个Manager
,直接调用[XManager loadData]
,顺便dismiss掉登录页面,就好了。参数会由XManager的paramSource提供,你只管调loadData就好了,paramSource的重要性就体现在这里了。回调什么的也在你上一次失败时的页面内,整个过程完全无缝,且基本没有耦合,还能做到token刷新后自动重发请求。我在自己App里也是这么做的,哈哈。
5、博主。在新的app中用到了您的架构。先感谢一下。菜鸟一个。原先用的block,现在改成delegate。略显不适应。现在遇到一个问题。在tableViewCell中,点击某个按钮需要进行请求。如下图。我要关注一个用户。请求调用应该写在哪。cell中,还是controller里。我现在在controller里调用。这里遇到了两个问题。
a. 请求完成后我如何找到对应的cell。比如第一个用户我没有关注。我点击关注,然后在控制器里进行请求。在请求前我是不是要保存当前cell所处的indexPath。否则请求完成后我就不知道更新哪个cell了。
b. 如果我先后点击关注第一个用户和第二个用户按钮。在Controller里我只有一个apiManager。我该怎么去同时请求关注这两个用户。
答:
-
其实你提出的是三个问题,在这里我分别针对你三个问题进行一下回答。
应该在哪里发请求?
在能够完成全部相关业务逻辑的主体中发送请求。就你这个需求来看,收到请求回调之后,你需要更新Cell界面,需要更新cell对应的dataSource中的相关标记,这些事情只有Controller能够完成。所以请求应当在Controller中发起。
请求完成之后如何找到对应的Cell?
你会看到NSURLRequest+AIFNetworkingMethods.h里面添加了一个requestParams,这样在得到response的时候,是能够获得request的,那么也就意味着能够获得对应的requestParams。
你可以考虑在params里面带上indexPath.row,那么在response得到的时候,就也能拿到indexPath.row了。不过如果不嫌麻烦,最好还是再加一个UserInfo属性,跟这个RequestParam一样,跟着response一起带回来,你拿到response的时候就可以知道是哪个cell了。
先后点击关注第一个用户和第二个用户按钮,如何请求?
请求还是正常请求的,其实关键问题还是在于区分拿到的请求是第一个用户还是第二个用户,就能解决了。