前言
以前一直沒有認(rèn)真的考慮過自己所掌握的iOS相關(guān)知識體系,今天老實說不是很想敲代碼 懶 ,正巧在簡書看到了 [hherima] 大大的博客鏈接,看了看覺得很棒消略,本著好記性不如爛筆頭的思想,根據(jù)前輩總結(jié)出來的知識樹瞎抛,梳理一下自己滿是漿糊的大腦艺演。雖說有一些東西年代的確頗為久遠(yuǎn)了 (看到不少2012、2013年的文章鏈接)婿失,但無傷大雅,依然非常值得一閱啄寡。
說的好像敲了就能掌握一樣……
我預(yù)感到這篇肯定又會跟裹腳布一樣又臭又長
8.1追加:寫不動了……
UIKit 系
一豪硅、UIViewController
1 . UIViewController 在iOS中的作用
總的來說,UIViewController有5個作用
1. 管理視圖(View Management)
2. 管理數(shù)據(jù)(Data Marshalling)
3. 作用于用戶交互(Use interactions)
4. 管理資源(Resource Management)
5. 屏幕適配(Adaptivity)
這個總結(jié)……怎么講挺物,其實略略有些過時懒浮,現(xiàn)下已經(jīng)不用這么“分工明確”的形容來描述UIViewController的作用了。特別是MVVM開發(fā)模式日漸流行的今天识藤,打開一個項目經(jīng)常會很驚奇的發(fā)現(xiàn)壓根就找不到Controller --> 其實沒消失砚著,只是被整合了。
2 . UIViewController的生命周期
本來想寫代碼的痴昧,后來發(fā)現(xiàn)還是這張圖表現(xiàn)的比較直觀稽穆,也去掉了目前已棄用的 - viewDidUnload 方法 ,Life cycle 會不會顯得高端點赶撰?
上面這是單個ViewController的生命周期(重點是View在其內(nèi)部的聲明周期)舌镶,當(dāng)涉及不同控制器之間的跳轉(zhuǎn)的時候,比如vc1
push to controller: vc2
或者pop回來的時候:
說好的敲呢豪娜?怎么都是截圖了餐胀!
3 . + (void)initialize +(void)load 這兩個方法的調(diào)用時機
Apple的文檔很清楚地說明了initialize和load的區(qū)別在于:load是只要類所在文件被引用就會被調(diào)用,而initialize是在類或者其子類的第一個方法被調(diào)用前調(diào)用瘤载。所以如果類沒有被引用進(jìn)項目否灾,就不會有l(wèi)oad調(diào)用;但即使類文件被引用進(jìn)來鸣奔,但是沒有使用墨技,那么initialize也不會被調(diào)用惩阶。
再簡單點說
+(void)load
// 控制器被加載后立刻運行,不沿用父類方法健提。
+ (void)initialize
// 只在明確表示使用時會被調(diào)用琳猫,延用父類方法。
4 . - viewDidLoad 私痹,- viewWillAppear 調(diào)用時機
按照Casa大大的說法脐嫂,viewDidLoad中,應(yīng)該只完成addSubview的操作紊遵,具體的setup账千,繪制,邏輯處理等等都不應(yīng)該塞在viewDidLoad中暗膜≡茸啵可能是因為我級別太低吧,暫時無法理解這種思想学搜。但viewDidLoad中負(fù)責(zé)加載UI控件是毋庸置疑的娃善,如果頁面比較簡單,也許可以把一些不復(fù)雜的數(shù)組處理也放在這里瑞佩。
viewDidLoad 和 viewWillAppear 在代碼中的出鏡頻率都挺高的聚磺,一般來說,如果在返回該控制器界面時炬丸,需要執(zhí)行一些刷新的操作時瘫寝,將reloadData操作放在 viewWillAppear 這里是比較好的一個選擇。
5 . 在UIViewController中配置橫豎屏
實話目前暫時還沒怎么遇到需要橫屏的需求稠炬,但不代表以后不會遇到
iOS - 視頻橫豎屏切換的一些事
上面這個鏈接里說了一些橫豎屏切換時的代碼焕阿,看著還不錯,先放在這里首启,有機會補上暮屡。
6 . 交互方式
基本的交互方式就是push 和 present(modal) 了,
對應(yīng)的回退方式是-popViewController 和 - dismiss 毅桃。
- pushViewController:(ViewController *) animate:(BOOL)
// -popViewController 默認(rèn)退回上一個界面栽惶,也可以指定退回到某個界面或者至RootController
- presentViewController:(ViewController *) animated:(BOOL) completion:
// 以模態(tài)的方式從屏幕底部彈出一個窗口,占據(jù)整個屏幕(默認(rèn)沒有導(dǎo)航條)
// 回退方式為dismiss該控制器
還有一種是將一個controller的view直接加載在另一個controller上
但是要注意奔残幔活外厂。
一個ViewController就寫的有點想死了……我這到底是在干嘛啊
二、UIView
1 . UIView中 frame 與bounds的區(qū)別
frame :相對父視圖中坐標(biāo)系的值代承;
bounds: 相對于自身的坐標(biāo)系的值汁蝶。
在有一些需要執(zhí)行UIView的- layoutSubViews 操作時,如果出現(xiàn)crash,
可以嘗試將 **[super layoutSubviews]** 移至函數(shù)的末端掖棉,即先重新布局墓律,再執(zhí)行該父類中的方法。
// 據(jù)說目前只有iOS7會出現(xiàn)該crash幔亥,待考證耻讽。
// 個人覺得應(yīng)該跟版本關(guān)系不大,還是代碼寫的有問題帕棉。
2 . 常用方法
只討論添加視圖针肥、控件的話,最常用的莫過于 - addSubview 了
- addSubview;
// 1. 向視圖中添加一個子控件
// 2. 添加的子控件會被塞到subviews數(shù)組的最后面
手寫自定義view的話香伴,[self.contentView addSubview:_adb]往往很多慰枕,
我個人喜歡堆在一起,比較有成就感……(其實不規(guī)范的)
此外即纲,還有不少其他的添加方法 :
// 將子控件view插入到subviews數(shù)組的index位置
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
// 將子控件view顯示到子控件siblingSubview的下面
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
// 將子控件view顯示到子控件siblingSubview的上面
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
// 將子控件view放到數(shù)組的最后面具帮,顯示在最上面
- (void)bringSubviewToFront:(UIView *)view;
// 將子控件view放到數(shù)組的最前面,顯示在最下面
- (void)sendSubviewToBack:(UIView *)view;
用法不盡相同低斋,視具體情況而定蜂厅。
3 . UIView動畫
使用 + animateWithDuration:可以執(zhí)行一些簡單的動畫效果;
在動畫完成后修改控件的alpha 或者執(zhí)行hidden操作膊畴,使其展現(xiàn)/隱藏在用戶面前掘猿。
// 代碼演示框留白,暫時想不到什么特別具有代表性的……
三礁遵、CALayer
1 . 同根同源轻绞,與UIView都繼承自NSObject,但中間少了UIResponder --> CALayer是一個抽象的簡單類佣耐,不能響應(yīng)用戶交互政勃;
2 . 主要作用就是在屏幕上展示繪制的矩形區(qū)域 ;
3 . UIView可以看做是CALayer的高級封裝 (代理) 兼砖。
四奸远、UIWindow
1 . 每一個iOS程序都有一個UIWindow ;
2 . keyWindow是指定的用來接收鍵盤以及非觸摸類的消息讽挟;而且程序中每一個時刻只能有一個window是keyWindow懒叛。
3 . 可以通過scale當(dāng)前的keyWindow來呈現(xiàn)一些縮放效果
五、UIImage 耽梅、UIImageView
關(guān)聯(lián)較多的兩個類薛窥,前者為顯示的具體實例,后者是容器
UIImageView 默認(rèn)是不具備用戶交互功能的,但是可以通過修改userInterface 并添加手勢來間接執(zhí)行用戶交互诅迷。
1 . UIImage的加載方法 (圖片的加載方式)
iOS內(nèi)存資源稀缺佩番,相對而言,圖片的展示又是比較占用資源的罢杉。因此UIImage也針對內(nèi)存方面有不同的加載方式趟畏。
1. 最常用的 imageNamed:
[UIImage imageNamed:@"xxxx"];
// 該方式加載的圖片會由系統(tǒng)緩存到cache中
2. imageWithContentsOfFile或者imageWithData
[UIImage imageWithContentsOfFile:path] ;
[UIImage imageWithData:data];
// 這兩種方式都是不緩存的 ,根據(jù)場景的不同加以選用
簡單的說滩租,imageNamed:適合相對較小的圖片赋秀,且經(jīng)常使用
其他的適合較大的圖片,或者只加載一次就完事了的持际。
PS:TableView中沃琅,因為存在復(fù)用機制,只出現(xiàn)一次的圖片用"ImageNamed"也沒啥毛病
其實隨著這些年移動端設(shè)備的內(nèi)存越來越大蜘欲,內(nèi)存大小已經(jīng)不算是特別揪心的問題了益眉,
但怎么講,好的習(xí)慣要保持姥份,這也是iOS流暢郭脂,受歡迎的原因之一
2 . 拉伸圖片。
舉例:下拉菜單澈歉,聊天氣泡等等都會用到
- resizeableImageWithCapInsets:
// 設(shè)置好了之后可以達(dá)到只拉伸中間一小塊區(qū)域展鸡,四周保持不變的效果。
3 . 加載gif 圖片
iOS的gif圖片似乎一直被人詬病埃难,無論是存儲還是什么莹弊,不過你要說蘋果搞不定gif相關(guān)我是不信的,那么最后只能歸結(jié)于蘋果的堅持 信仰 了涡尘。
iOS如何加載gif圖片
六忍弛、UILabel
1 . 默認(rèn)是不支持從從頂部往下一行行排列文本的(自然的行文方式),不過變通的方法很多:使用封裝好的三方庫 , 或者設(shè)置numberOfLines = 0 后考抄,動態(tài)改變label的高度 细疚。
2 . 重寫drawTextInRect:方法,可以自定義繪制區(qū)域川梅,比如可設(shè)置Inset
3 . 有一些奇怪的用法疯兼,比如給label添加刪除線(之前遇到一次);
4 . YYText真的很好很強大 (雖然嚴(yán)格的說不算是label)贫途。
// 重寫inset
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.textInsets)]
七、UIButton
1 . 善于使用contentEdgeInsets,可以設(shè)置按鈕內(nèi)的文本邊距
2 . UIButton的imageView frame 默認(rèn)就是原始圖片的大小丢早,如果需要適配姨裸,需要加一些修改
3 . UIButton 上的title左對齊,僅設(shè)置label是沒用的
設(shè)置按鈕標(biāo)題左對齊
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// 這個屬性是button獨有的
八、UITextField
1 . 跟UITextView算是一母雙生啦扬,很多地方很相近中狂。
2 . 單行輸入,在AlertSheet 時候不好使扑毡,得自己定制……
3 . 跟鍵盤的聯(lián)動要注意相應(yīng)的邏輯關(guān)系
任意界面隱藏鍵盤的方法:
[textfield resignFirstResponder]
正常情況下 , 足以應(yīng)付大部分的 隱藏 / 收起 鍵盤的需求胃榕。
但在某些特殊情況,略略有些麻煩瞄摊,好在還有其他的解決方案
1. ControllerA出來時候勋又,隱藏當(dāng)前任意view的鍵盤。
[[[UIApplication sharedApplication] keyWindow] endEditing:YES]换帜;
2. 加入不方便獲取第一響應(yīng)者,還可以使用這個方法
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponser)
to:nil from:nil forEvent:nil];
九楔壤、UIScrollView
嗯……好像也沒什么好說……
雖說相對于UITableView之類沒什么存在感,但其各種代理方法還是經(jīng)常用到的惯驼,另外注意contentOffset 滾動位置
蹲嚣、contentSize 實際尺寸
、contentInset 滾動邊距
這三個很像的家伙……別混淆了祟牲。
scrollView 不能滾動的三種可能的原因
1 - 沒有設(shè)置contentSize;
2 - scrollEnabled = NO;
3 - 沒有接收到觸摸事件:userInteractionEnabled = NO;
十隙畜、UITableView
這里能扯的東西實在是太多了,感覺單獨開一篇都不算過分,但為了行文的流暢 來都來了,還是弄一下意思意思……
1 . 重用機制 (緩存池三部曲)
// 記得先注冊
1. 設(shè)定可重用標(biāo)識符负拟,使用static修飾
2. 從緩存池中獲取
// - dequeueReusableCellWithIdentifier 從重用池中獲取,可能是nil
// - dequeueReusableCellWithReuseIdentifier 同上鼻疮,但是不會是nil
3. 如果無法從緩存池中獲取,再創(chuàng)建一個新的
其實能講的還很多,但核心機制還是上面說的幾條
2 . 插入、移動运杭、刪除TableView 的section 或者 cell需要嚴(yán)格遵循順序
如上圖所示:
1. 首先更新數(shù)據(jù)源中的相關(guān)數(shù)據(jù)
2. 調(diào)用相應(yīng)的collection view方法刪除或者插入section或item
// 必須嚴(yán)格遵守順序,不然就是數(shù)組越界等等等一系列問題了
3 . TableView右側(cè)音序索引 (通訊錄右側(cè)拼音索引)
其實很簡單 蛋哭,只是代碼不常用而已
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return _pinyinIndexArray;
}
_pinyinIndexArray當(dāng)然不是憑空冒出來的县习,初始化一下即可
_pinyinIndexArray = @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H".....];
4 . 刷新列表
普通狀態(tài)下涮母,使用[tableView reloadData] 即可
某些需求要求只刷新某一行cell或者某一個section 可以使用下面的方法:
//一個section刷新
NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:2];
[tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
//一個cell刷新
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:3 inSection:0];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
5 . sectionHeader 浮動效果
UITableViewStylePlain模式下谆趾,header不浮動
十一、UIDevice
常用的幾種UIDevice相關(guān)方法
// 1. 設(shè)備名
[UIDevice currentDevice].name;
// 2. 系統(tǒng)版本號
[[UIDevice currentDevice].systemVersion doubleValue];
// 3. 屏幕旋轉(zhuǎn)方向
[[UIDevice currentDevice] orientation]
// 4. 區(qū)分iPad還是iPhone
[UIDevice currentDevice].userInterfaceIdiom;
十二叛本、UIScreen
1 . 最常用的應(yīng)該還是根據(jù)UIScreen 獲取屏幕的寬高沪蓬,可以寫成宏來進(jìn)行相關(guān)計算 - > 等比例適配
2 . 根據(jù)UIScreen 繪制1像素的線 <-> 保持邊距不變,等比例拉伸来候。
2用的應(yīng)該不多跷叉,個人還是比較習(xí)慣直接使用UIView或者UIImageView
直接繪制一條寬度為1的作為separtorLine `
娘的終于寫完了……一部分……
NSObject 系
一、NSObject
NSObject,老實說光聽這個名字就知道一定很屌云挟!梆砸,事實上也的確如此,他是iOS中幾乎所有類的基類和協(xié)議园欣。絕大多數(shù)非視圖型號的文件帖世,subClass寫這個也是八成都不會錯
具體使用:
1 . - isKindOfClass:和 - isMemberOfClass:的異同
same: 都是用來確定/檢測某個對象的從屬關(guān)系 (belong to class )
diff: - isKindOfClass: 還能檢測出對象是否是由class派生出來的
// 別糾結(jié),用isKindOfClass (優(yōu)先級較高)
2 . respondsToSelector: 用法
需要調(diào)用協(xié)議里的可選方法時沸枯,我們不知道遵循協(xié)議的類是否已經(jīng)實現(xiàn)了這些方法日矫。
這時respondsToSelector方法來判斷遵循協(xié)議的類是否已經(jīng)實現(xiàn)了某個方法。
if ([self.delegate respondsToSelector:@selector(doSomething:)]) {
[_delegate doSomething:string];
}
// 本質(zhì)上仍然是從安全性角度考慮绑榴,加的一道防護哪轿,防止程序崩潰
- conformsToProtocol :
// 可以測試某個對象或者類是否遵守了協(xié)議
3 . description 調(diào)試方法
允許一個對象返回一個字符串來描述它的內(nèi)容;這個常用于調(diào)試debug
- (NSString *)description{
return [NSString stringWithFormat:@"age = %i, string = %@",_age,_str];
}
// 某些情況下比NSLog好用的多翔怎,用于打印程序員需要的信息
4 . encodeWithCoder: 和 initWithCoder:方法
NSCoding協(xié)議中僅有的兩個方法:
// 對象編譯它的實例變量
- encodeWithCoder:
// 允許一個對象初始化它自身的解碼實例變量
- initWithCoder:
還有一些感覺更純理論 (如 "__weak是如何實現(xiàn)自動置nil的")窃诉,也的確略微底層了一些 看都看不懂寫個毛,先挖個坑赤套,有機會填褐奴。
二、NSString & NSMutableString
1 . NSString作為屬性時候于毙,用copy還是strong修飾敦冬?
看在什么情況下吧
基本上,如果是作為Model的屬性時唯沮,都選用copy
如果是在Controller或者View層脖旱,根據(jù)實際情況來進(jìn)行選用 (參考NSMutableArray應(yīng)該還是選用strong比較好)
二、NSArray & NSMutableArray
1 . 深拷貝 & 淺拷貝
2 . containsObject
此函數(shù)在對比數(shù)組中元素的時候介蛉,調(diào)用元素的isEqual的返回值萌庆。
三、NSDictionary & NSMutableDictionary
1 . 大致上跟NSArray差不多币旧,但取值時候践险,最好先判斷object的類型
// 判斷類型
if ([object isKindOfClass:[NSString class]]) {
// code here
};
四、NSNumber ,NSInterger ,NSUInterger ,NSRange
1 . 注意使用場合吹菱,%zd %ld 等等的區(qū)別即可巍虫。
無符號長整型用的場合沒有想象中的多
五、NSDate & NSDateFormatter & NSCalendar
1 . 目前接觸的比較多的是根據(jù)服務(wù)器返回的國際標(biāo)準(zhǔn)時間戳經(jīng)過初始化后改為較為"X小時前" "X天前" 這樣比較直觀的表示類型鳍刷。
2 . 進(jìn)行時間比較占遥,獲取需要的時間段。 參考新浪微博的時間戳處理
有些時候會顯示有8小時的時間差:
根本原因是格林威治時間與北京時間(東八區(qū))的時差输瓜,以后臺返回的時間為準(zhǔn)
// 解決代碼
NSDate *date = [NSDate date];
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate: date];
NSDate *localeDate = [date dateByAddingTimeInterval:interval];
NSLog(@"enddate=%@",localeDate);
六瓦胎、NSFileManager
1 . 刪除文件的時候先判斷是否存在是個好習(xí)慣
好像還有別的用法芬萍,一時想不起來,先挖個坑
七搔啊、NSTimer
1 . NSTimer需要跟NSRunLoop協(xié)同工作才會有效柬祠,即定時器需要正確加入到運行循環(huán)中才能生效,比如自動圖片輪播器负芋、或者定時提醒/推送等瓶盛。
2 . 但是由于runLoop同時又管理著各種各樣的資源,所以NSTimer的精確性不是非常高(應(yīng)付一般的需求足夠了)示罗〕兔ǎ總的來說,NSTimer并不是一種實時的機制蚜点,會存在些許延遲轧房,延遲的程度跟當(dāng)前的執(zhí)行情況有一定關(guān)系 。
// 每隔ti秒绍绘,調(diào)用一次aTarget的aSelector方法奶镶,yesOrNo決定了是否重復(fù)執(zhí)行這個任務(wù)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
// 通過invalidate方法可以停止定時器的工作,一旦定時器被停止了陪拘,就不能再次執(zhí)行任務(wù)厂镇。
// 只能再創(chuàng)建一個新的定時器才能執(zhí)行新的任務(wù)
- (void)invalidate;
// 啟動定時器:
– (void)fire
// 暫停
[timer setFireDate:[NSDatedistantFuture]];
八、其他的一些常用項
1 . NSLog
常用的 ** 暴力 ** 打印 左刽,在項目中最好設(shè)置專門的Debug用的Log宏捺信。
2 . NSUserDefaults
可以用來做一些簡單的本地存儲/讀取操作
1. 用來存儲一些數(shù)據(jù)量較小的屬性/對象,限于:
NSString, NSNumber, NSDate, NSArray, NSDictionary
2. 并不是立刻寫入的欠痴,可能會需要等待一段時間迄靠,如果需要立刻同步,需要執(zhí)行:
[[NSUserDefaults standardUserDefaults] synchronize]
舉例:
// 存儲UISwitch的值
- (IBAction)switchChanged:(id)sender{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; //獲取 NSUserDefaults 單例
[userDefaults setBool:_theSwitch.on forKey:@"switchValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// 讀取并賦值
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL sw = [userDefaults boolForKey:@"switchValue"];
[_theSwitch setOn:sw];
用來判斷是不是程序安裝后第一次進(jìn)入App很方便
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"firstInstall"]){
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"firstInstall"];
NSLog(@"第一次啟動"); //do something ...
} else {
NSLog(@"不是第一次啟動"); //do something else ...
}
3 . NSClassFromString & NSStringFromClass
顧名思義喇辽,從字符串中獲取類 / 從類名中獲取字符串
似乎是有一些黑科技在里面掌挚,達(dá)到邏輯解耦的效果
Foundation系
這里的知識點實在是太過于零散了,也比較抽象菩咨,更多的在于理解起碼要知道是個什么玩意吠式, 就不按照上面的 一、二抽米、三特占、分類了,
NSIndexPath 鏈?zhǔn)浇Y(jié)構(gòu)缨硝,tableView中用的相對多一點
初始化[NSIndexPath indexPathForRow:0 inSection:1];
NSError
處理網(wǎng)絡(luò)請求的時候經(jīng)常會遇到
NSException
挖坑待埋
NSStringEncoding
NSString的編碼格式摩钙,處理某些格式轉(zhuǎn)換時需要用到
NSProgressIndicator
挖坑待埋
NSBoundle
相當(dāng)于一個文件目錄類罢低,包括了程序中使用的資源:圖片
查辩,音頻片段
胖笛,nib
文件等, [NSBoundle mainBloundel] 后調(diào)用
NSNetServiceBrowser
在 Cocoa 層, NSNetService API 提供了一個接口, 用于發(fā)布和解析 Bonjour 服務(wù)的地址信息. 可以通過 NSNetServiceBrowser API 探測網(wǎng)絡(luò)上可用的服務(wù). 發(fā)布 Bonjour 服務(wù)(甚至是使用 Cocoa 層的 API)需要理解 Coer Foundation 才能配置好通信所需的 socket.
說的好玄乎宜岛,聽不懂啊……
NSValue
可以包裝任何一個對象 ===> 用NSValue 將struct存到NSArray 和 NSDictionary中
NSURLSession
iOS9中取代了原來冗長的NSUrlConnection 系A(chǔ)PI 长踊,
主要使用NSURLSession 及其子類 NSURLSessionTask
主要提供了以下功能
1. 通過URL將數(shù)據(jù)下載到內(nèi)存
2. 通過URL將數(shù)據(jù)下載到文件系統(tǒng)
3. 將數(shù)據(jù)上傳到指定URL
4. 在后臺晚上上述功能
NSURLRquest
緩存策略
,主要用來包裝/指定項目中比較具體的請求信息模式
擁有好幾種不同的策略萍倡,根據(jù)使用場合略有區(qū)別身弊。
NSInputStream & NSOutputStream socket編程
挖坑待埋
其實就是沒用過……
NSPredicate
謂詞查詢,原理和用法都類似于SQL中的where
NSLayoutConstraint
AutoLayout 的核心所在列敲,絕大多數(shù)三方的布局或計算寬高等的庫都只是變著法子為控件添加各種各種 NSLayoutConstraint 約束 不知道說的對不對阱佛,前輩說的
NSLock & NSRecursiveLock & NSCondition 多線程鎖
本質(zhì)上是為了防止多份線程同時調(diào)用同一資源可能引發(fā)的錯誤。
目前接觸過加鎖都是比較簡單的戴而,也算是一個坑吧凑术。
@synchronized {
//todo
}
上面這個同樣也是同步鎖,在項目中用來在執(zhí)行某些特殊讀取操作的時候可以考慮加上所意。
講真的我已經(jīng)后悔寫這一塊了淮逊,毛用沒有,徒勞打擊自己的自信心
還真不是一次搞的定的扶踊,先偷個懶吧……