前言 |
终于,在大学毕业前完完整整经历了一个商业项目。但在完成开发的时候,正值大三下期末考试期间,无赖地着眼于实现本身匆匆完成了功能需求(只是前期的要求,原因你懂得!),就去忙着复习准备考试了。因为我想尽可能地努力以获去高分来达到某种目的,所以这就需要更多的时间付出了。前期的草率也为后期的功能模块的增加及优化埋下了隐患,也有部分原因是实验室的项目规格本身就与市场上开发公司所做的有比较大的差异,即:UI设计不明确、App图标不完整、缺少完整的开发流程等。
这一整个过程走下来,还是遇到了很多麻烦,而这些麻烦都可以用所谓的经验来规避,这也是为什么企业招聘员工更喜欢有经验的员工的原因。废话就这么多,Let’s begin!
细数百度地图的几大坑点 |
之前也参与过业务集中于地图的项目开发,只是开发任务不在这一块。App使用的地图框架就是百度地图SDK。而国内的第三方地图开发框架有高德地图和百度地图,但出于对未知的变数考虑,还是决定选用百度地图做为技术支持。这就是坑点的开始!
- - 代理方法不响应 - -
看看下面这个方法是干啥的:
/**
*当点击annotation view弹出的泡泡时,调用此接口
*@param mapView 地图View
*@param view 泡泡所属的annotation view
*/
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view;
当前我所使用的版本是3.0.0,并且地图上的标注的气泡视图是自定义实现的。按道理这个方法会在弹出泡泡时响应,然而实现上并没有。
- - API设计不完善 - -
项目中需要在地图上添加覆盖物,而与之对应的是覆盖物需要被移除。按照Apple的设计风格,我自信满满地敲下了如下的这种代码:
//度娘:不好意思,我们没有这种API!
[self.mapView removeAllOverlays];
[self.mapView removeAllAnnotations];
但我只能这样写:
//度娘:嗯!孺子可教也,我们就喜欢你这种调用方式!
[self.mapView removeOverlays:self.mapView.overlays];
[self.mapView removeAnnotations:self.mapView.annotations];
对于地图上的标注:id <BMKAnnotation>
用户可以自定义实现,并且也提供了重用机制,这很nice。Demo(日语发音:但是),标注的气泡却不能被重用。
还有就是那一堆神一样的警告,可能是Apple太苛刻,Xcode太智能。Anyway,撰写开发文档的哥们,实在太不细心了,就因为你文档注释不规范,让编译器警告几十个错误,让有强迫症的兄弟怎么活啊?
word天,江河决堤啊 |
内存泄漏是老生常谈的问题,也是App性能检测的一个过程。于是,我忐忑不安的打开了Leak,运行!
……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……✖︎……
崩溃中……
获奖感言:谁能告诉我,有没有这样的人,能写出一行行不会泄漏的代码。留得住老板器重的目光,再辛苦也都值得!
淡定淡定,遇事淡定!先看看是什么导致了内存泄漏,咦!怎么都指向了引用的第三方框架呢?方法如下:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
然后在运行过程中观察App的内存占用,发现一个明显的事实:每次网络访问后,必然会导致内存增加零点几兆。说明确实在网络请求结束后有不能释放的对象存在,怀着这样的疑问,真心
询问了度娘,发现有很多关于这个问题的文章。心里一下子舒坦多了,毕竟不是只有我遇到了这个问题。解决办法主要是将manager设计为返回一个单例对象,而这种方法是会导致后面网络请求失败(网友回答)。在权衡之后,我还是按照AFNetworking作者给出的Demo中解决办法,即新建请求类继承自AFHTTPSessionManager(一个奇怪的问题是:[AFHTTPSessionManager manager]返回的对象为什么在ARC下不能被释放)并返回一个单例对象,就像这样:
+ (instancetype)sharedManager {
static SYHTTPSessionManager *_manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_manager = [[SYHTTPSessionManager alloc] initWithBaseURL:nil];
_manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
});
return _manager;
}
很遗憾,内存泄漏还是没有排除干净,但是已经从之前八九十的量级减至十几了。问题还是出现在第三方框架上:百度地图、支付宝RSA加密组件、AFNetworking(问题已经没有出现在之前的方法里),我们在享受第三方框架给我们带来的便利的同时或许还应该思考它们可能给项目带来的弊端,就比如说这里提到的内存泄漏问题。
总结 |
其实,最大的心得是深刻体会到了前期的需求分析与架构设计的重要性。如果有很多共享数据的话,就需要考虑统一数据的包装形式。如果任务分工有重叠的地方,就应当让代码逻辑之间互不冲突。人无远虑,必有近忧,凡此种种,都是为了让我们有个愉快的过程,更享受编写代码的过程,have fun!