轉(zhuǎn)載自? http://blog.csdn.net/hherima/article/details/50714866
本文旨在總結(jié)iOS知識網(wǎng)絡,該知識網(wǎng)絡羅列出常見UIKit,F(xiàn)oundation的對象特點和一些使用經(jīng)驗;文本編輯采用樹的形式,對知識點進行羅列,并標注一些使用經(jīng)驗(★)希望對初學者有用或給一些解決疑難雜癥者提供思路;某些知識點會深入探討;通過總結(jié)希望站在一個較高平臺的角度全觀Objective-C。知識樹中有些是原創(chuàng)文章,有些則是轉(zhuǎn)載網(wǎng)絡上iOS大神的文章。筆者會盡量詳細的介紹各個知識點。當然一個人的知識面是相當有限的,在給各位讀者提供知識參考的同時,歡迎大家對本文提意見。
/->UIViewController
|ViewController在iOS只是一個非常重要的概念,其在一個App中所扮演的角色,
|(1) View Management:管理View ? ??(2) Data Marshalling:管理數(shù)據(jù)
|(3) User Interactions:響應用戶交互?(4) Resource Management:管理資源
|(5) Adaptivity:適配不同的屏幕尺寸空間的變化
|+ (void)initialize +(void)load?的調(diào)用時機,區(qū)別【點擊】
|ViewDidLoad調(diào)用時機:當view被首次使用的時候,某些情況可提升性能
|->UIView
|frame 和bound 的區(qū)別【點擊】
|frame 是相對父試圖坐標的值;?bound是本身坐標系統(tǒng)的值
|layoutSubviews【點擊】需要將[super layoutSubviews];放到最后,不然iOS7有可能會有這個崩潰
|★"Auto Layout still required after executing -layoutSubviews” iOS7上崩潰sdk缺陷【點擊】
|每一個視圖有唯一的父視圖【點擊】。addsubview操作把它從上一個父試圖中移除
|善于使用hidden?使用animateWithDuration簡單地控制頁面切換效果
|使用animateWithDuration簡單地控制頁面切換效果【點擊】
|★簡單動畫?animateWithDuration【點擊】
|->CALayer
|CALayer是個簡單的類,它是用來在屏幕上顯示內(nèi)容展示的矩形區(qū)域.【容芳志出品點擊】
|直接從NSObject繼承,少了UIResponder類,固CALayer悲催的不能響應任何用戶事件【點擊】
|->UIWindow
|每一個IOS程序都有一個UIWindow
|UIWindow有三個層級,分別是Normal,StatusBar,Alert【點擊】
|keyWindow是指定的用來接收鍵盤以及非觸摸類的消息,
|而且程序中每一個時刻只能有一個window是keyWindow。
|->UIImage
|加載圖片幾種方式【點擊】
|[UIImage imageNamed:@“xxx”] 系統(tǒng)緩存到cache中
|[UIImage imageWithContentsOfFile:path] 不緩存
|[UIImage imageWithData:data] ?不緩存
|★拉伸圖片,四角保持不變resizableImageWithCapInsets:
|★加載gif圖片【點擊】
|->UILabel【點擊】
|沒有上下居中對齊,可以使用TTTAttributedLabel
/
/->UIKit
|\
||->UIButton
||設置顏色,文字一定要指定button狀態(tài)
||善于使用contentEdgeInsets,可以設置文本邊距【點擊】
||設置圓角可layer.cornerRadius
||->UITextfield
||隱藏鍵盤,[textfield resignFirstResponder]
||★任意頁面隱藏鍵盤【點擊】
||->UITableView
||復用,注意重寫?- (void)prepareForReuse
||dequeueReusableCellWithIdentifier 從重用池中獲取,可能是nil
||dequeueReusableCellWithReuseIdentifier?同上,但是不會是nil
||插入,刪除,移動section或item的順序,需遵循下面兩個步驟【點擊】
||1. 更新dataSource的數(shù)據(jù)
||2. 調(diào)用相應的collection view方法刪除或者插入section或item
||★非常嚴格的條件:,在更新collection view之前,先更新datasource,
||因為collection view總是假設你已經(jīng)準備好打他source了 否則collection view收到錯誤的item,并造成crash
||右側(cè)音序條【點擊】
||UITableView上拉、下拉原理【點擊】
||AsyncDisplayKit 流暢的解決方法【點擊】
||★當tableView正在滾動的時候,如果reloadData,偶爾發(fā)生App crash的情況【點擊】
||->UIDevice
||設備名 [UIDevice currentDevice].name,
||系統(tǒng)版本號 [[UIDevice currentDevice].systemVersion doubleValue];【點擊】
||屏幕旋轉(zhuǎn)方向 [[UIDevice currentDevice] orientation]
||區(qū)分iPad還是iPhone [UIDevice currentDevice].userInterfaceIdiom);
||->UIScreen
||如何正確的繪制1像素的線【點擊】
||保證邊距不變,內(nèi)容等比例拉伸【點擊】
|\->自動布局
|Masonry
|
|/->NSObject既是對象也是協(xié)議,可以將對象自動置nil 比如 int = 0 bool = NO
||幾乎所有類的基類或者協(xié)議【點擊】
||isKindOfClass:和isMemberOfClass:,通過這兩種方法可以確定一個類的從屬關系\
||后者測試一個接收器是否是一個指定類的實例;而后者可以測試類的從屬關系。
||respondsToSelector: 方法測試一個接收器是否通過selector實現(xiàn)(implements)了一個標志符話的方法
||description方法,允許一個對象返回一個字符串來描述它的內(nèi)容;這個常用于調(diào)試debug
||encodeWithCoder: 和 initWithCoder:方法,NSCoding協(xié)議中僅有的組成成員\
||第一個允許對象編譯它的實例變量,第二個允許一個對象初始化它自身的解碼實例變量。
||conformsToProtocol:方法,測試接收器(對象或者類)符合一個給定的協(xié)議(protocol)
||★__weak如何實現(xiàn)對象值自動設置為nil的【點擊】
||->NSString & NSMutableString
||NSString作為屬性時候,用copy還是strong修飾?
||strong是單純的增加對象的引用計數(shù),而copy操作是執(zhí)行了一次深拷貝【點擊】
||->NSArray &?NSMutableArray
||NSArray 各種遍歷方式,倒序遍歷【點擊】
||NSArray簡便初始化方法@[@"1",@"2"];
||淺拷貝。數(shù)組本身使用地址,但是數(shù)組item仍是舊對象【Apple 官方解釋點擊】
||無論copy、arrayWithArray、copyWithZone 數(shù)組內(nèi)對象并沒有變。
||只是copy出來的array是新地址,arrayWithArray出來的數(shù)組也是新地址。
||深拷貝。數(shù)組本身使用地址,但是數(shù)組item是新地址
||[[NSArray alloc] initWithArray:someArray copyItems: YES];
||深拷貝時候,數(shù)組中的item必須實現(xiàn)NSCopying協(xié)議并實現(xiàn)copyWithZone:
||★防止NSArray was mutated while being enumerated
||array包含array的情況深拷貝。NSArray* trueDeepCopyArray = [NSKeyedUnarchiver \
||unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];
||->NSDictionary &?NSMutableDictionary
||取值時候,最好判斷object的類型。? ? if ([object isKindOfClass:[NSString class]]){ //todo};
||->NSNumber 和 NSInteger NSRange
||前者專門用來裝基礎類型的對象,把整型、單精度、雙精度、字符型等基礎類型存儲為對象
||->NSNullFMDB數(shù)據(jù)庫,使用的時候崩潰
||JsonKit轉(zhuǎn)換以后會生出相應的[NSNull null]對象【點擊】
||->NSData字節(jié)緩沖區(qū)
||->NSUserDefaults【點擊】
||可用于APP setting默認值不好用,SDK bug
||設置WebVIew的UA【點擊】
||->NSDate & NSDateFormatter &NSCalendar
||可判斷過去幾個小時,還是幾天?- (NSDateComponents *)?components:fromDate:toDate:options:
||可獲取時間戳
||->NSCoding & NSCoder僅有的兩個方法,數(shù)據(jù)的序列號和反序列化【點擊】
||- (void)encodeWithCoder:(NSCoder *)aCoder;
||- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
||->NSCopying &?NSZone
| ? ? ? ? ? ? ? ? ? ?|+ (instancetype)allocWithZone:深拷貝,類似于memcpy這樣的C方法【點擊】
||->NSAutoreleasePool
||降低內(nèi)存峰值【點擊】
||->NSFileManager刪除文件的時候先判斷是否存在是個好習慣
||->NSTimer
||NSTimer 簡單使用【點擊】
||★NSTimer定時器時間并不精確,類似于公交車進站,堵車就不準時【點擊】
||->NSLog暴力打印,常用于測試【點擊】
|/
|->Foundation
|\
||->NSIndexPath鏈式結(jié)構(gòu);tableview用的比較多【點擊】
||初始化?[NSIndexPath indexPathForRow:0 inSection:1];
||->NSError網(wǎng)絡變成經(jīng)常用到
||->NSException
||->NSStringEncoding NSString的編碼格式,了解即可【點擊】
||->NSProgressIndicator
||->NSBundle?是個目錄,包含了程序使用的資源,如圖像,聲音,編譯好的代碼,nib文件【點擊】
||->NSNetServiceBrowser
||->NSValue可以包裝任意一個對象,可以用NSValue將struct存到NSArray和NSDictionary中?!?a target="_blank" rel="nofollow">點擊】
||->NSURLSession&NSURLSessionTask【點擊】NSURLSession提供的功能:
||通過URL將數(shù)據(jù)下載到內(nèi)存【點擊】
||通過URL將數(shù)據(jù)下載到文件系統(tǒng)
||將數(shù)據(jù)上傳到指定URL
||在后臺完成上述功能【點擊】
||->NSURLRequest 包裝了網(wǎng)絡請求的信息【點擊】
||->NSInputStream & NSOutputStream socket編程【點擊】
||->NSPredicate
||謂語查詢,原理和用法都類似于SQL中的where【點擊】
||->NSLayoutConstraint
||->NSLock & NSRecursiveLock & NSCondition多線程鎖
||最基本的同步鎖【點擊】
||@synchronized{//todo} 同樣也是同步鎖【點擊】
||事實上信號量也能實現(xiàn)鎖的目的,信號量和鎖的區(qū)別【點擊】第二篇【點擊】
||->NSMethodSignature
/|配合NSInvocation實現(xiàn)消息轉(zhuǎn)發(fā)【點擊】
iOS|->NSInvocation直接調(diào)用 某個對象的消息【點擊】
\|iOS中可以直接調(diào)用 某個對象的消息 方式有2種performSelector:withObject: 和NSInvocation
||->NSSet無序的對象集合,用處少
||->NSUrl基本使用,包含F(xiàn)ile URL和File path【點擊】
||->AVPlayer基本使用【點擊】
||獲取視頻時間長度【點擊】
|\->NSNotificationCenter同步的機制【點擊】注意防止重復,相似的機制還有delegate,observer,block
|
|/->創(chuàng)建push原理介紹、證書制作、測試push 專輯【點擊】
||"iOS push全方位解析(一)【譯文】"——iOS PUSH概述【點擊】
||"iOS push全方位解析(二)【譯文】"——生成OpenSSL證書,Provisioning Profile【點擊】
||"iOS push全方位解析(三)【譯文】"——一個極簡的demo,并測試一下push【點擊】
|/
|->Push
|\
||★iOS6、7、8、9 Push的演化【點擊】,但目前還是不盡人意(APP 無法獲取通知欄消息數(shù)目)
||★php寫的可以在本機發(fā)送iOS push程序【點擊】
||iOS7 Background Remote Notification(后臺遠程通知——靜默push)【點擊】
|\->有一些三方push SDK:極光push
|
|->block必須掌握
|block專輯【點擊】;Block帶有局部變量的匿名函數(shù);iOS開發(fā)尤其實用
|【block編程第一篇】 block編程熱點介紹(官方文檔翻譯的)【點擊】
|【block編程第二篇】 block捕獲變量和對象【點擊】
|【block編程第三篇】block內(nèi)存管理——如何驗證block在棧上,還是堆上【點擊】
|【block編程第四篇】block的實現(xiàn)【點擊】
|【block編程第五篇】block中使用 weak–strong dance 技術避免循環(huán)引用【點擊】
|->多線程
|iOS有三種多線程編程的技術,分別是:【點擊】
|1、NSThread?下面會講到
|2、Cocoa NSOperation?下面會講到
|3、GCD 下面會講到
|這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單。
|
|/->引用計數(shù)(retainCount)
||retain 引用計數(shù)+1 對象alloc時,引用計數(shù)為1, release引用計數(shù)-1.引用計數(shù)=0時候,真正釋放
||autoRelease,自動釋放對象【點擊】
||->便捷構(gòu)造方法?iOS
||對象在自動釋放池中,不需要開發(fā)者手動釋放,比如下面的方法
||NSString的stringWithString
||NSArray的arrayWithObjects:和arrayWithArray:
||UIImage的imageNamed:
||->內(nèi)存管理高級指南【官方譯點擊】
||->內(nèi)存管理實踐【點擊】
|/
|->內(nèi)存管理【專欄點擊】
|\
||->MRC手動引用計數(shù)。release和retain成對兒
|\->ARC自動引用計數(shù)
|★強烈建議使用ARC
|★禁止在函數(shù)內(nèi)返回局部變量指針,不然就是野指針!
|★容易引起循環(huán)引用的地方【點擊】
|
|/->Runtime運行時特點
||objc_setAssociatedObject【點擊】給對象增加屬性,一般配合類別使用
||object_getClass得到一個實例的類【點擊】
||objc_copyImageNames ?獲取指定類所在動態(tài)庫【南峰子出品點擊】
||objc_copyClassList??創(chuàng)建并返回一個指向所有已注冊類的指針列表【點擊】
||class_xxx系列函數(shù)【點擊】
||class_copyPropertyList??獲取類的屬性
||class_isMetaClass?判斷是否為元類
||class_getName 獲取類名
||class_copyIvarList?拷貝類的實例變量列表
||class_getInstanceMethod?獲取實例方法
||->CFRunnloop【ibireme出品點擊】
||RunLoop 實際上就是一個對象,這個對象管理了其需要處理的事件和消息
||并提供了一個入口函數(shù)來執(zhí)行上面 Event Loop 的邏輯
|/
|->iOS 動態(tài)機制
|\
||->消息傳遞objc_msgSend【點擊】【南峰子出品點擊】
||如果向某對象傳遞消息,那就會使用動態(tài)綁定機制來決定需要調(diào)用的方法
||objc_msgSend有兩個隱藏參數(shù),消息接收對象 方法的selector ,即(self,_cmd)
||->消息轉(zhuǎn)發(fā)message forwarding【點擊】
||就是對象在接收到無法解讀的消息之后會發(fā)生什么情況
||(1)?+(BOOL) resolveInstanceMethod:(SEL)selector?類是否新增一個實例方法
||(2)?resolveClassMethod 是否新增了類方法
||(3)?-(id) forwardingTargetForSelector:(SEL)selector 能不能把這條消息轉(zhuǎn)給其他接收者來注冊
||(4)-(void) forwardInvocation:(NSInvocation*)invocation??消息派發(fā)系統(tǒng)
||(5)最后若都不能處理消息,則doesNotRecognizeSelector: 會拋出異常
||★當我們不能確定一個對象是否能接收某個消息時,會先調(diào)用respondsToSelector:來判斷一下
||->方法調(diào)配技術method swizzling?用于調(diào)試【南峰子出品點擊】
||SEL又叫選擇器,是表示一個方法的selector的指針,每一個方法都對應著一個SEL。
||IMP?它是objetive-C 方法(method)實現(xiàn)代碼塊的地址,實際上是函數(shù)指針,指向方法實現(xiàn)的首地址
||Swizzling應該總是在+load中執(zhí)行
|在 iOS 中,幾乎所有類都是 responder,比如 UIWindow、UIView、UIControl、UIControllers 等
|當手指去觸摸屏幕上 UIView 的實例對象 aView。產(chǎn)生一個觸摸事件 UIEventTypeTouches
|而接收觸摸事件的對象 aView,就是一個 responder object。
|initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate
|
|/->沙盒(Sandbox)iOS沙盒機制【容芳志出品點擊】
||每個應用程序都有自己的存儲空間
||應用程序不能翻過自己的圍墻去訪問別的存儲空間的內(nèi)容
||應用程序請求的數(shù)據(jù)都要通過權限檢測,假如不符合條件的話,不會被放行。
||->GroupiOS8+數(shù)據(jù)共享,例如擴展(Extension)共享數(shù)據(jù)【點擊】
||->SpotlightiOS9+ 系統(tǒng)搜索?!竟俜絛emo點擊】
||->GCD(Grand Central Dispatch)iOS開發(fā)有一個強有力的多線程工具【點擊】
||多線程入門【raywenderlich出品點擊】
||系統(tǒng)提供一個叫做 主隊列(main queue)
||系統(tǒng)還提供一個叫做全局調(diào)度隊列(Global Dispatch Queues)有四個優(yōu)先級
||開發(fā)者自己創(chuàng)建隊列(串行,或者并行)
||★至少有五個隊列任你處置:主隊列、四個全局調(diào)度隊列,再加上任何你自己創(chuàng)建的隊列。
||GCD 深入理解:第一部分【點擊】
||GCD 深入理解:第二部分【點擊】
||開發(fā)常見方法介紹
||dispatch_after?延后工作
||Dispatch Groups?會在整個組的任務都完成時通知你
||dispatch_semaphore_t ?信號量,讓你控制多個消費者對有限數(shù)量資源的訪問?!?a target="_blank" rel="nofollow">點擊】
||dispatch_semaphore_wait? 使得信號量-1,當=0時候阻塞
||dispatch_semaphore_signal? 釋放信號量,即信號量+1
||
||->CoreData數(shù)據(jù)持久化,相比sqlite有下面優(yōu)勢【點擊】
||數(shù)據(jù)庫字段或者表有更改會導致crash,CoreData的版本管理和數(shù)據(jù)遷移變得非常有用,\
||手動寫sql語句操作還是麻煩一些。
||不光能操縱SQLite,CoreData和iCloud的結(jié)合也很好,如果有這方面需求的話優(yōu)先考慮
||并不是直接操縱數(shù)據(jù)庫,比如:使用CoreData時不能設置數(shù)據(jù)庫的主鍵,目前仍需要手動操作。
||效率上其實跑程序時感覺不出來,畢竟手機上的數(shù)據(jù)不能跟網(wǎng)站的數(shù)據(jù)和訪問量相提并論。
|/
|->iOS 特殊封裝&平臺特性
|\
||->類別(Category)擴展(Extension)微小區(qū)別【點擊】
||堪稱iOS編程的精髓【點擊】
||->KVC鍵值編碼
||在IOS的中,沒有絕對的私有,包括方法和變量,可以通過字符獲取屬性【點擊】
||->KVO鍵值觀察
||依賴Runtime 和KVC 一個新的類會動態(tài)被創(chuàng)建。詳細原理【點擊】另外一篇【點擊】
||★比如:Tableview上拉下拉動畫檢測offset;播放視頻,獲取視頻時長時候等
||為什么KVO不成對兒調(diào)用,會崩潰?
||->多任務
||->3D Touch,通過在plist中添加菜單,然后app實現(xiàn)下面的方法。進入APP
||- (void)application: performActionForShortcutItem: completionHandler:
||->spotlight通過系統(tǒng)搜索,進入APP【點擊】
|\->Touch ID如何使用iOS 8 指紋識別,代碼、實例【點擊】
|
|
\->iOS工具
CrashHlytics Crash統(tǒng)計工具
AFHttp 和 ASIHttp
SDImage
------------------------------------------------------------------------------------------
參考文獻:《Objective-C高級編程:iOS與OS X多線程和內(nèi)存管理》日本人寫的;
《Effective Objective C 2.0:編寫高質(zhì)量iOS與OS X代碼的52個有效方法》;
《Objective-C基礎教程(第2版)》