成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

寒哥教你學 iOS - 經(jīng)驗漫談

移動開發(fā)
本篇文章主要講解 4個問題:load妙用、aop面向切面編程、NSNumber Or Int、@()適配64位

[[148033]]

本篇文章主要講解 4個問題

  1. load妙用

  2. aop面向切面編程

  3. NSNumber Or Int

  4. @()適配64位

1 讓appDelegate 減少負擔

經(jīng)過漫長時間的學習 你終于掌握了iOS大法 你找到了份iOS開發(fā)的工作 信誓旦旦的要開始你的coding生涯 老板對你非常器重 然后告訴你 我覺得你的技術 是非常刁的 那這個項目就你自己來搞吧 啊哦這就意味著這個項目你就從頭到尾處理 從軟件的架構 到頁面的展示 都交給你嘍 ??

用著自己的半吊子水平 papapa的 coding 決心一定要把代碼封裝好 寫的漂亮 (其實是聽大神說 封裝 其實自己不太懂)

項目到了尾聲 老板告訴你我們的app 我們的app 將來得來個分享到朋友圈的功能吧 不然怎么體現(xiàn)我產(chǎn)品的牛逼

然后你聽說友盟比較好使(有廣告的嫌疑) 你去友盟看了他們的文檔 他告訴你你要在 appdelegate didFinishLaunch方法里面寫了這個東西

  1. ?[UMSocialData?setAppKey:@"XX"]; 
  2. ????//?????注冊微信 
  3. ?[UMSocialWechatHandler?setWXAppId:@"XXX"??appSecret:@"XX"?url:@""]; 
  4. ????//????注冊QQ 
  5. ?[UMSocialQQHandler?setQQWithAppId:@"XXX"?appKey:@"XXX"?url:@""]; 

過了幾天 老板又說 我們需要統(tǒng)計下我頁面的信息 你接入了友盟的統(tǒng)計 在appdelegate didFinishLaunch又 多了行代碼

需求是無窮無盡 我需要bug統(tǒng)計(fir hud) 提醒用戶評分系統(tǒng)(iRate) 推送(jPush 信鴿 個推。。)

當初你決心一定要把代碼封裝的完美 寫的漂亮的心早就被老板的需求徹底打敗了

別擔心 寒哥教你小技巧

不知道你們用過 IQKeyBoardManageiRate這種智能庫沒

大牛的readme 寫了這段話

  1. Key?Features 
  2. 1)?CODELESS,?Zero?Line?Of?Code?不需要寫任何代碼 
  3. 2)?Works?Automatically?//自動工作 
  4. 3)?No?More?UIScrollView?//不需要scrollview 
  5. 4)?No?More?Subclasses?//不需要繼承父類 
  6. 5)?No?More?Manual?Work?//不需要配置 
  7. 6)?No?More?#imports?//不需要導入 

其實不神奇 只是大牛用了 + load這個方法

學習OC都知道這個代碼會在一個類被加載到運行庫中就會被自動調用 這不就實現(xiàn)了 自動調用

寫一個類繼承自NSObject

  1. #import?@interface?ThirdPartService?:?NSObject 
  2. @end 
  3. ?#import?"ThirdPartService.h" 
  4. ?#import?"UMSocial.h" 
  5. ?#import?"UMSocialWechatHandler.h" 
  6. ?#import?"UMSocialQQHandler.h" 
  7. ?#import??#import?@implementation?ThirdPartService 
  8. ?+?(void)load?{ 
  9. static?dispatch_once_t?onceToken; 
  10. dispatch_once(&onceToken,?^{ 
  11. ????//????TODO??這里是我自己測試的??fir?hud 
  12. ????[FIR?handleCrashWithKey:@"XX"]; 
  13. ????//????友盟 
  14. ????[UMSocialData?setAppKey:@"XX"]; 
  15. ????//?????隱藏未安裝的平臺 
  16. ????[UMSocialConfig?hiddenNotInstallPlatforms:@[UMShareToQQ,UMShareToQzone,UMShareToWechatSession,UMShareToWechatTimeline]]; 
  17. ????//?????注冊微信 
  18. ????[UMSocialWechatHandler?setWXAppId:@"XX"?appSecret:@"XX"?url:@""]; 
  19. ????//????注冊QQ 
  20. ????//????TODO???QQ的不是真的 
  21. ????[UMSocialQQHandler?setQQWithAppId:@"XX"?appKey:@"XX"?url:@""]; 
  22. ????//????TODO????UM統(tǒng)計 
  23. ????[MobClick?startWithAppkey:@""]; 
  24. ????[MobClick?setCrashReportEnabled:NO]; 
  25. ????NSLog(@"第三方服務注冊完畢"); 
  26. }); 
  27. @end 

類似于定位也可以這樣寫

blob.png

模塊和服務完全拆開

但是有的服務 如APNS需要LaunchOption 那就只能寫在appdDelegate 不過這樣的話已經(jīng)摘除很多代碼了 只剩下幾個固定的 到時候再修改appDelegate就會感覺非常清晰 了

2 ViewController繼承?

接著上面講 我們接入了友盟統(tǒng)計 友盟統(tǒng)計最基本的東西就是 統(tǒng)計頁面的pv

blob.png

友盟的這樣寫 對于新手的我們就覺得這不就so easy嗎

我打開了某個vc(HomeViewController)

在代碼里面寫上了這句

  1. -(void)viewWillAppear:(BOOL)animated?{ 
  2. ???[super?viewWillAppear:animated]; 
  3. #ifndef?DEBUG 
  4. ???[MobClick?beginLogPageView:NSStringFromClass([self?class])]; 
  5. #endif 
  6. -(void)viewWillDisappear:(BOOL)animated?{ 
  7. ????[super?viewWillDisappear:animated]; 
  8. #ifndef?DEBUG 
  9. ??[MobClick?endLogPageView:NSStringFromClass([self?class])]; 
  10. #endif 

然后我一個項目中可能有幾十個 甚至上百個頁面需要統(tǒng)計pv 我總不能每個節(jié)目都這樣寫吧

聰明的我們想到了繼承

如MyBaseViewController:UIViewController

這樣就要做一件事 把我們項目中所有繼承自UIViewController的類全部改為繼承自MyBaseViewController 然而你真的覺得這樣好嗎 我們一個項目中有幾十個控制器 我就要把每個控制器改一遍

這種重復性的工作一是無聊 而是容易出錯 你復制著復制者就會遺漏掉某個類 重要的是 我們項目中很多類并不是直接繼承自UIViewController 有的可能是UITableViewController UICollectionViewContr0ller UINavigationController 甚至不常用的UISearchDisPlayController UIPopoverController ?UIPresentController 是不是突然覺得這么多啊啊 ??

這也不是坑的 坑的是將來你混成了大牛 招了個小弟 你告訴他你所有的類都要繼承自我寫的各種父類 新手總是會不經(jīng)意見犯錯誤 有些類忘記繼承了 后期查起來難度非常大 浪費時間 所以這種設計是不合理的

  • 寒哥再次教你黑魔法 Method swizzling

關于這個是干嘛的 自行百度

這里有一篇來自NSHipster博主的文章 英文

中文翻譯

還有一篇解釋runtime的文章傳送門

實踐

用方法交叉 我們就可以攔截吸引的方法了 上代碼了

這樣就做到了面向切面編程(AOP)的思想

上代碼

  1. #import?@interface?UIViewController?(AOP) 
  2. #warning??運行時?改變一下方法?做一些切面編程比如?統(tǒng)計?等等 
  3. ?@end 
  4. ?#import?"UIViewController+AOP.h" 
  5. ?#import?#import??@implementation?UIViewController?(AOP) 
  6. ?+?(void)load?{ 
  7. ???static?dispatch_once_t?onceToken; 
  8. ??dispatch_once(&onceToken,?^{ 
  9. ????Class?class?=?[self?class]; 
  10. ????//?When?swizzling?a?class?method,?use?the?following: 
  11. ????//?Class?class?=?object_getClass((id)self); 
  12. ????swizzleMethod(class,?@selector(viewDidLoad),?@selector(aop_viewDidLoad)); 
  13. ????swizzleMethod(class,?@selector(viewDidAppear:),?@selector(aop_viewDidAppear:)); 
  14. ????swizzleMethod(class,?@selector(viewWillAppear:),?@selector(aop_viewWillAppear:)); 
  15. ????swizzleMethod(class,?@selector(viewWillDisappear:),?@selector(aop_viewWillDisappear:)); 
  16. }); 
  17. ?void?swizzleMethod(Class?class,?SEL?originalSelector,?SEL?swizzledSelector)???{ 
  18. Method?originalMethod?=?class_getInstanceMethod(class,?originalSelector); 
  19. Method?swizzledMethod?=?class_getInstanceMethod(class,?swizzledSelector); 
  20. BOOL?didAddMethod?= 
  21. class_addMethod(class
  22. ????????????????originalSelector, 
  23. ????????????????method_getImplementation(swizzledMethod), 
  24. ????????????????method_getTypeEncoding(swizzledMethod)); 
  25. if?(didAddMethod)?{ 
  26. ????class_replaceMethod(class
  27. ????????????????????????swizzledSelector, 
  28. ????????????????????????method_getImplementation(originalMethod), 
  29. ????????????????????????method_getTypeEncoding(originalMethod)); 
  30. }?else?{ 
  31. ????method_exchangeImplementations(originalMethod,?swizzledMethod); 
  32. ?} 
  33. ?-?(void)aop_viewDidAppear:(BOOL)animated?{ 
  34. [self?aop_viewDidAppear:animated]; 
  35. ?-(void)aop_viewWillAppear:(BOOL)animated?{ 
  36. [self?aop_viewWillAppear:animated]; 
  37. #ifndef?DEBUG 
  38. ???[MobClick?beginLogPageView:NSStringFromClass([self?class])]; 
  39. #endif 
  40. ?-(void)aop_viewWillDisappear:(BOOL)animated?{ 
  41. ????[self?aop_viewWillDisappear:animated]; 
  42. #ifndef?DEBUG 
  43. ????[MobClick?endLogPageView:NSStringFromClass([self?class])]; 
  44. #endif 
  45. ?-?(void)aop_viewDidLoad?{ 
  46. [self?aop_viewDidLoad]; 
  47. if?([self?isKindOfClass:[UINavigationController?class]])?{ 
  48. ????UINavigationController?*nav?=?(UINavigationController?*)self; 
  49. ????nav.navigationBar.translucent?=?NO; 
  50. ????nav.navigationBar.barTintColor?=?GLOBAL_NAVIGATION_BAR_TIN_COLOR; 
  51. ????nav.navigationBar.tintColor?=?[UIColor?whiteColor]; 
  52. ????NSDictionary?*titleAtt?=?@{NSForegroundColorAttributeName:[UIColor?whiteColor]}; 
  53. ????[[UINavigationBar?appearance]?setTitleTextAttributes:titleAtt]; 
  54. ????[[UIBarButtonItem?appearance] 
  55. ?????setBackButtonTitlePositionAdjustment:UIOffsetMake(0,?-60
  56. ?????forBarMetrics:UIBarMetricsDefault]; 
  57. //????self.view.backgroundColor?=?[UIColor?whiteColor]; 
  58. self.navigationController.interactivePopGestureRecognizer.delegate?=?(id)self; 
  59. ?} 
  60. ?@end 

圖片代碼一份 方便觀看

blob.png

blob.png

我們充分利用了黑魔法達到了面向切面編程的好處

思想來源這里http://casatwy.com/iosying-yong-jia-gou-tan-viewceng-de-zu-zhi-he-diao-yong-fang-an.html

黑魔法非毒藥 遵守一個規(guī)范寫出來的代碼是不會Crash的 只要能幫我們解決問題就是好東西

黑魔法性能 有瓶頸? 都到runtime的底層了 你還擔心有瓶頸 ?少年安心使用就好了 ? 不服 可以用Time Profiel測試

黑魔法也非萬能 ?像 我們在導航控制器要封裝手勢 統(tǒng)一管理左側返回按鈕 ?這些東西 還是繼承來得好

技術就是工具 黑貓,白貓,抓住老鼠就是好貓

#p#

3 網(wǎng)絡訪問參數(shù)到底用基本數(shù)據(jù)類型還是對象

下面看兩個方法

blob.png

 
  1. ?+?(void)getDataAtPageNo:(NSNumber?*)pageNo?PageSize:(NSNumber?*)pageSize? 
  2. complete:(CompleteBlock)complete?{ 
  3. NSMutableDictionary?*param?=?[NSMutableDictionary?dictionary]; 
  4. ????if?(pageSize)?{ 
  5. ????????[param?setObject:pageSize?forKey:@"pageSize"]; 
  6. ???} 
  7. ?[param?setObject:pageNo?forKey:@"pageNo"]; 
  8. //?SendRequest 
  9. ?+?(void)getData2AtPageNo:(long?)pageNo?PageSize:(long?)pageSize? 
  10. ?complete:(CompleteBlock)complete?{ 
  11. ?????NSMutableDictionary?*param?=?[NSMutableDictionary?dictionary]; 
  12. ????????[param?setObject:@(pageSize)?forKey:@"pageSize"]; 
  13. ????????[param?setObject:@(pageNo)?forKey:@"pageNo"]; 
  14. //?SendRequest 
  15. ?} 

在訪問網(wǎng)絡請求時 對于有參數(shù)的請求 設計一個方法 主流為以上兩種

  1. 使用對象當做參數(shù)

  2. 使用基本數(shù)據(jù)類型做參數(shù)

一般情況下 這并沒有什么大的區(qū)別 但是寒哥給出的意見是Never出現(xiàn)基本數(shù)據(jù)類型

一般情況下 開發(fā)者可能覺得并沒有什么區(qū)別 下面我給大家舉個例子

在設計一個分頁展示數(shù)據(jù)的時候: 在頁面上的邏輯就是 默認加載第一頁 每頁長度為10 (Server端的同學一般都很友好 默認情況下 不傳每頁的長度就是10個) 但是傳了就會覆蓋掉后臺寫的默認參數(shù) 如傳了20 Server就吐20條數(shù)據(jù)

  1. 在第一中設計方案中: 可能在某個控制器中保留一個PageNo PageSize 的對象的成員變量 ,在下拉刷新或者上拉加載的時候 會傳遞對應的參數(shù)給請求方法 , 如果沒有特殊需求的話pageSize 對象可有可無 也就是有可能為nil ,那在對應的param可能就沒有這個參數(shù)傳遞給Server 。

    Server 就會交還給我們某頁的20條數(shù)據(jù)

  2. 在 第二種設計方案中 : 可能也在某個控制器中保留一個PageNo pageSize的基本數(shù)據(jù)類型的成員變量, 在訪問網(wǎng)絡請求時交給對應的方法 , 一般沒有特殊需求我們也不會對PageSize專門設值 但是 基本數(shù)據(jù)類型在OC 和C語言這種傳統(tǒng)的編程語言中是有默認值的 為0,雖然我們沒有給pageSize 賦值 但是默認系統(tǒng)默認給了0這個初始值 那么傳遞到Server的時候 就會覆蓋掉Server 寫的默認pageSize=10 這樣的請求既不會報錯 也不會返回數(shù)據(jù)

超級難調試

所以在網(wǎng)絡訪問中 寒哥給出的意見就是Never出現(xiàn)基本數(shù)據(jù)類型

4 用NSNumber比基本數(shù)據(jù)類型的好處 ? 64位適配問題

我們一般都用來當做網(wǎng)絡請求的參數(shù) 緩存或者展示到頁面

  1. 對于網(wǎng)絡請求的參數(shù) 因為NSDictionary只能放對象 所以NSNumber最好的方式
  2. 緩存 無論緩存到plist 還是KeyArchive 都是需要對象的所以NSNumber也非常合適
  3. 展示到頁面

我見過這樣給頁面上賦值的朋友

blob.png

我們看到這樣貌似并沒有什么不妥

但是我們把設備切換到iPhone5S以下 也就是32位的設備

blob.png

注意這里有Warning

為什么呢 我們來看下NSInteger的頭文件

blob.png

在32下設備是Int 在64位是long

我們都知道蘋果不允許不支持64位的app上架 但是貌似我們從來沒有為32位和64位做適配

其實不然 在printf 和NSLog 時 對應%d %zd %f 占位符是非常嚴格的 如果不對項目就會造成意外的結果

blob.png

blob.png

其實拿到一個NSNumber我們并不知道他到底是int long unsigned int Bool 直接針對某個類型轉換是有風險的 但是其實Clang 給我們提供了個非常好用的Macro @()

blob.png

NSNumber并不是一個簡單的類 它是cocoa 中 類簇的實現(xiàn)參考資料

http://www.cocoachina.com/ios/20140109/7681.html

http://www.cocoachina.com/ios/20150106/10848.html

http://www.cocoachina.com/ios/20141218/10688.html

責任編輯:倪明 來源: 簡書
相關推薦

2018-07-02 09:32:36

OceanBase列式存儲

2010-06-07 15:09:44

訪問MySQL數(shù)據(jù)庫

2010-06-04 18:32:48

MySQL數(shù)據(jù)庫

2015-08-26 10:36:32

ios開發(fā)漫談

2015-08-31 10:11:43

iOS大項目開發(fā)

2014-07-22 09:53:08

芬蘭數(shù)據(jù)中心

2010-07-22 12:53:17

SQL Server數(shù)

2013-08-12 11:18:00

2011-06-24 14:59:41

外鏈

2011-07-28 10:01:19

IOS 內存優(yōu)化

2020-02-26 08:16:32

AIoT人工智能物聯(lián)網(wǎng)

2021-07-26 17:22:02

Java

2018-04-03 10:30:35

2011-05-06 16:10:26

打印技巧

2012-12-21 12:37:24

2013-05-15 15:05:53

2009-02-06 10:39:22

NAS設備升級NAS

2021-12-03 09:04:53

線程設計進程池

2013-03-08 10:47:03

重構

2017-02-20 17:41:12

SDN網(wǎng)絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费小视频在线观看 | 国产成人艳妇aa视频在线 | 99久久久99久久国产片鸭王 | 中文字幕在线精品 | 美国十次成人欧美色导视频 | 日韩乱码在线 | 国产高潮av | 伊人网在线看 | 99精品在线观看 | 一区二区精品 | 99久久国产| 国产一区二区三区四区 | 精品日韩在线 | 国产91在线 | 亚洲 | 特黄毛片 | 91视频在线观看免费 | 国产午夜精品一区二区三区嫩草 | 日本在线网站 | 91免费在线 | 亚洲精品免费视频 | 韩日中文字幕 | 欧美日一区二区 | 国产免费一区二区 | 国产真实乱对白精彩久久小说 | 欧美男人的天堂 | 成人免费视频观看 | 国产在线观看网站 | av天天看| 在线小视频 | www.青娱乐| 日韩在线观看视频一区 | 国产视频二区在线观看 | av在线免费看网址 | 2018天天干天天操 | 国产7777 | 日韩欧美国产一区二区 | 精品久久久久久久人人人人传媒 | 在线日韩不卡 | 中文字幕一区二区三区四区五区 | 日韩免费一区二区 | 综合色播 |