黑马程序员技术交流社区
标题:
ios 学习注意事项
[打印本页]
作者:
xqlyn123
时间:
2015-11-26 23:00
标题:
ios 学习注意事项
load妙用
aop面向切面编程
NSNumber Or Int
@()适配64位
1 让appDelegate 减少负担
经过漫长时间的学习 你终于掌握了iOS大法 你找到了份iOS开发的工作 信誓旦旦的要开始你的coding生涯 老板对你非常器重 然后告诉你 我觉得你的技术 是非常刁的 那这个项目就你自己来搞吧 啊哦这就意味着这个项目你就从头到尾处理 从软件的架构 到页面的展示 都交给你喽 ??
用着自己的半吊子水平 papapa的 coding 决心一定要把代码封装好 写的漂亮 (其实是听大神说 封装 其实自己不太懂)
项目到了尾声 老板告诉你我们的app 我们的app 将来得来个分享到朋友圈的功能吧 不然怎么体现我产品的牛逼
然后你听说友盟比较好使(有广告的嫌疑) 你去友盟看了他们的文档 他告诉你你要在 appdelegate didFinishLaunch方法里面写了这个东西
[UMSocialData setAppKey:@"XX"]; // 注册微信 [UMSocialWechatHandler setWXAppId:@"XXX" appSecret:@"XX" url:@""]; // 注册QQ [UMSocialQQHandler setQQWithAppId:@"XXX" appKey:@"XXX" url:@""];过了几天 老板又说 我们需要统计下我页面的信息 你接入了友盟的统计 在appdelegate didFinishLaunch又 多了行代码
需求是无穷无尽 我需要bug统计(fir hud) 提醒用户评分系统(iRate) 推送(jPush 信鸽 个推。。)
当初你决心一定要把代码封装的完美 写的漂亮的心早就被老板的需求彻底打败了
别担心 寒哥教你小技巧
不知道你们用过
IQKeyBoardManage
和
iRate
这种智能库没
大牛的readme 写了这段话
Key Features1) CODELESS, Zero Line Of Code 不需要写任何代码2) Works Automatically //自动工作3) No More UIScrollView //不需要scrollview4) No More Subclasses //不需要继承父类5) No More Manual Work //不需要配置6) No More #imports //不需要导入其实不神奇 只是大牛用了 + load这个方法
学习OC都知道这个代码会在一个类被加载到运行库中就会被自动调用 这不就实现了 自动调用
写一个类继承自NSObject
#import @interface ThirdPartService : NSObject@end #import "ThirdPartService.h" #import "UMSocial.h" #import "UMSocialWechatHandler.h" #import "UMSocialQQHandler.h" #import #import @implementation ThirdPartService + (void)load {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{ // TODO 这里是我自己测试的 fir hud [FIR handleCrashWithKey:@"XX"]; // 友盟 [UMSocialData setAppKey:@"XX"]; // 隐藏未安装的平台 [UMSocialConfig hiddenNotInstallPlatforms:@[UMShareToQQ,UMShareToQzone,UMShareToWechatSession,UMShareToWechatTimeline]]; // 注册微信 [UMSocialWechatHandler setWXAppId:@"XX" appSecret:@"XX" url:@""]; // 注册QQ // TODO QQ的不是真的 [UMSocialQQHandler setQQWithAppId:@"XX" appKey:@"XX" url:@""]; // TODO UM统计 [MobClick startWithAppkey:@""]; [MobClick setCrashReportEnabled:NO]; NSLog(@"第三方服务注册完毕");});}@end类似于定位也可以这样写
模块和服务完全拆开
但是有的服务 如APNS需要LaunchOption 那就只能写在appdDelegate 不过这样的话已经摘除很多代码了 只剩下几个固定的 到时候再修改appDelegate就会感觉非常清晰 了
2 ViewController继承?
接着上面讲 我们接入了友盟统计 友盟统计最基本的东西就是 统计页面的pv
友盟的这样写 对于新手的我们就觉得这不就so easy吗
我打开了某个vc(HomeViewController)
在代码里面写上了这句
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated];#ifndef DEBUG [MobClick beginLogPageView:NSStringFromClass([self class])];#endif}-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated];#ifndef DEBUG [MobClick endLogPageView:NSStringFromClass([self class])];#endif}然后我一个项目中可能有几十个 甚至上百个页面需要统计pv 我总不能每个节目都这样写吧
聪明的我们想到了继承
如MyBaseViewController:UIViewController
这样就要做一件事 把我们项目中所有继承自UIViewController的类全部改为继承自MyBaseViewController 然而你真的觉得这样好吗 我们一个项目中有几十个控制器 我就要把每个控制器改一遍
这种重复性的工作一是无聊 而是容易出错 你复制着复制者就会遗漏掉某个类 重要的是 我们项目中很多类并不是直接继承自UIViewController 有的可能是UITableViewController UICollectionViewContr0ller UINavigationController 甚至不常用的UISearchDisPlayController UIPopoverController ?UIPresentController 是不是突然觉得这么多啊啊 ??
这也不是坑的 坑的是将来你混成了大牛 招了个小弟 你告诉他你所有的类都要继承自我写的各种父类 新手总是会不经意见犯错误 有些类忘记继承了 后期查起来难度非常大 浪费时间 所以这种设计是不合理的
寒哥再次教你黑魔法 Method swizzling
关于这个是干嘛的 自行百度
这里有一篇来自NSHipster博主的文章
英文
中文翻译
还有一篇解释runtime的文章
传送门
实践
用方法交叉 我们就可以拦截吸引的方法了 上代码了
这样就做到了面向切面编程(AOP)的思想
上代码
#import @interface UIViewController (AOP)#warning 运行时 改变一下方法 做一些切面编程比如 统计 等等 @end #import "UIViewController+AOP.h" #import #import @implementation UIViewController (AOP) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; // When swizzling a class method, use the following: // Class class = object_getClass((id)self); swizzleMethod(class, @selector(viewDidLoad), @selector(aop_viewDidLoad)); swizzleMethod(class, @selector(viewDidAppear:), @selector(aop_viewDidAppear:)); swizzleMethod(class, @selector(viewWillAppear:), @selector(aop_viewWillAppear:)); swizzleMethod(class, @selector(viewWillDisappear:), @selector(aop_viewWillDisappear:));});} void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {Method originalMethod = class_getInstanceMethod(class, originalSelector);Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);BOOL didAddMethod =class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));if (didAddMethod) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));} else { method_exchangeImplementations(originalMethod, swizzledMethod);} } - (void)aop_viewDidAppear:(BOOL)animated {[self aop_viewDidAppear:animated];} -(void)aop_viewWillAppear:(BOOL)animated {[self aop_viewWillAppear:animated];#ifndef DEBUG [MobClick beginLogPageView:NSStringFromClass([self class])];#endif} -(void)aop_viewWillDisappear:(BOOL)animated { [self aop_viewWillDisappear:animated];#ifndef DEBUG [MobClick endLogPageView:NSStringFromClass([self class])];#endif} - (void)aop_viewDidLoad {[self aop_viewDidLoad];if ([self isKindOfClass:[UINavigationController class]]) { UINavigationController *nav = (UINavigationController *)self; nav.navigationBar.translucent = NO; nav.navigationBar.barTintColor = GLOBAL_NAVIGATION_BAR_TIN_COLOR; nav.navigationBar.tintColor = [UIColor whiteColor]; NSDictionary *titleAtt = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; [[UINavigationBar appearance] setTitleTextAttributes:titleAtt]; [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];}// self.view.backgroundColor = [UIColor whiteColor];self.navigationController.interactivePopGestureRecognizer.delegate = (id)self; } @end
作者:
黑马小向
时间:
2015-11-26 23:22
看不懂--!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2