1.appearance
用appearance拿到對(duì)象,然后用拿到的對(duì)象設(shè)置被appearance注釋()的屬性,就會(huì)使整個(gè)項(xiàng)目的這種控件都變?yōu)樵O(shè)置的樣子,例如:
UISwitch *switch = [UISwitch appearance];
switch.onTintColor = [UIColor redColor];
這樣設(shè)置就會(huì)使整個(gè)項(xiàng)目的switch控件開(kāi)啟顏色變?yōu)榧t色
注意:如果該控件已經(jīng)顯示出來(lái),則設(shè)置無(wú)效,要想設(shè)置有效需要將整個(gè)父控件移除,然后再加回去.
2.隱藏宏
在Build Settings中搜索DEBUG,在Debug那一欄中添加宏,這樣就可以在項(xiàng)目中使用該宏,但無(wú)法找到宏的詳細(xì)內(nèi)容
注意:宏命名的時(shí)候不能全是小寫(xiě)字母,至少有一個(gè)大寫(xiě)字母或至少有一個(gè)數(shù)字
3.只執(zhí)行一次的操作
如果代碼塊想在程序中只執(zhí)行一次,可以用dispatch_once或者懶加載
4.tabBar
需求:在tabBar中央加一個(gè)按鈕
解決思想:重寫(xiě)tabBar,在layoutSubview方法中,重新布局系統(tǒng)自帶的按鈕(UITabBarButton,系統(tǒng)私有類(lèi)),在中央空出一塊地方,然后添加按鈕
1.cell之間分割線(重寫(xiě)setFrame方法)
思路:
在cell原有的高度下減1,這樣就可以實(shí)現(xiàn)不用添加View就有分割線,且分割線和背景色一樣
具體實(shí)現(xiàn):
由于cell的重復(fù)利用機(jī)制,所以在設(shè)置的時(shí)候改是無(wú)法實(shí)現(xiàn)的,但是每次重用cell的時(shí)候都會(huì)調(diào)用cell的setFrame方法,所以在自定義cell中重寫(xiě)setFrame方法,并且在調(diào)用[super setFrame]之前,將高度減1,這樣就可以實(shí)現(xiàn)不添加View就有分割線這一需求.不光如此,還可以設(shè)置左右邊距,將x加1,將width減2.
擴(kuò)展:
我們自己封裝的控件,不想在外界被人修改size,可以在[super setFrame]之前設(shè)置一個(gè)固定的size,但是bounds也會(huì)修改size,所以也要重寫(xiě)setBounds方法
2.網(wǎng)絡(luò)請(qǐng)求的成功和失敗
當(dāng)域名錯(cuò)誤時(shí),請(qǐng)求就會(huì)失敗;當(dāng)域名正確但參數(shù)錯(cuò)誤時(shí),請(qǐng)求返回的數(shù)據(jù)依然是成功的,只是返回一個(gè)空數(shù)據(jù),所以在請(qǐng)求成功的block塊中也要進(jìn)行一次判斷,判斷返回?cái)?shù)據(jù)是否為空
3.網(wǎng)絡(luò)請(qǐng)求延時(shí)
在網(wǎng)絡(luò)請(qǐng)求時(shí),為提高用戶體驗(yàn),在屏幕中央添加一個(gè)蒙版,提示用戶正在網(wǎng)絡(luò)請(qǐng)求.但有時(shí)網(wǎng)絡(luò)請(qǐng)求延時(shí)很高,以防引起用戶不耐,所以在請(qǐng)求時(shí),用戶隨時(shí)可以點(diǎn)擊返回按鈕退出界面,并且在dealloc中移除蒙版.但是block中強(qiáng)引用控制器,造成控制器無(wú)法銷(xiāo)毀,造成在退出界面后,蒙版依然存在這種情況
解決方案:不要讓block強(qiáng)引用控制器(在block塊中不使用self),或者將self包裝成弱指針:
__weak typeof(self) weakSelf = self;
但是還有問(wèn)題,以AFNetworking為例,由于網(wǎng)絡(luò)管理者在內(nèi)部被強(qiáng)引用,所以在控制器銷(xiāo)毀的時(shí)候,依然在進(jìn)行網(wǎng)絡(luò)請(qǐng)求.
解決方法1:用weak類(lèi)型的屬性引用網(wǎng)絡(luò)管理者,在銷(xiāo)毀控制器的時(shí)候調(diào)用:
[self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];
這個(gè)方法的意思:取消所有正在網(wǎng)絡(luò)請(qǐng)求的任務(wù),執(zhí)行這個(gè)方法之后,管理者依然可用.
解決方法2:依然是用weak類(lèi)型屬性醫(yī)用網(wǎng)絡(luò)管理者,在銷(xiāo)毀控制器的時(shí)候調(diào)用:
[self.manager invalidateSessionCancelingTasks:YES];
這個(gè)方法的意思:使session停止請(qǐng)求,執(zhí)行這個(gè)方法之后,session銷(xiāo)毀,管理者和session是一對(duì)一的,導(dǎo)致管理者不能用.
但是還有問(wèn)題!取消任務(wù)也被認(rèn)為是請(qǐng)求失敗,會(huì)執(zhí)行請(qǐng)求失敗的block代碼塊,所以在退出界面后彈出一個(gè)請(qǐng)求失敗的彈框,所以要在請(qǐng)求失敗的block代碼塊中判斷error的錯(cuò)誤代碼,取消請(qǐng)求的錯(cuò)誤代碼是:NSURLErrorCancelled(-999)
4.weak和IBOutlet
被weak引用的屬性,當(dāng)沒(méi)有強(qiáng)指針指向?qū)傩詴r(shí),屬性會(huì)立即銷(xiāo)毀;如果被weak引用的屬性有IBOutlet修飾時(shí),并不會(huì)被馬上銷(xiāo)毀,而是在代碼塊過(guò)后銷(xiāo)毀,因?yàn)樵贗BOutlet內(nèi)部有個(gè)隱藏的強(qiáng)指針引用著.
5.layer(圖層)
layer是一個(gè)相對(duì)耗時(shí)的操作,會(huì)造成卡頓,盡量少使用layer
6.const和宏
宏相對(duì)比較消耗性能
const只是拿常量的值使用,性能較好,但是const只能修飾常量,不能修飾方法和編譯之前不確定的值.const修飾右邊的內(nèi)容,例如:
NSString *const name = @"wbw"; 表示不能修改指針的指向
NSString const *name = @"wbw"; 表示不能修改指針指向的內(nèi)容地址的值
7.常量書(shū)寫(xiě)規(guī)范
僅限文本件使用的不可變?nèi)肿兞?要加上:static和const,例如:
static NSString *const name = @"wbw";
整個(gè)項(xiàng)目都可以使用的不可變?nèi)肿兞?創(chuàng)建一個(gè).h和.m文件,在.m文件中創(chuàng)建被const修飾的變量(例如: NSString *const name = @"wbw";),在.h文件中聲明(例如: UIKIT_EXTERN NSString *const name;),在.pch文件中導(dǎo)入.h文件
注:UIKIT_EXTERN就是extern,蘋(píng)果內(nèi)部包裝了一層,可能內(nèi)部有所優(yōu)化
8.控件不能響應(yīng)點(diǎn)擊事件,原因可能有
1.userInteractionEnabled = NO;
2.enabled = NO;
3.父控件的userInteractionEnabled = NO;
4.父控件的enabled = NO;
5.控件已超出父控件的邊框范圍
9.自定義tableView的footerView
先將tableView的footerView替換成自定義的footerView,然后設(shè)置自定義footerView的高度時(shí),發(fā)現(xiàn)設(shè)置高度無(wú)效,而自定義footerView的高度又必須根據(jù)子控件而變化,解決方法:
1.在計(jì)算完子控件高度后,將自定義footerView重新設(shè)置為tableView的footerView:
UITableView *tableView = (UITableView *)self.superView;
tableView.tableFooterView = self;
2.根據(jù)公式計(jì)算出行數(shù),行數(shù)*子控件的高度,設(shè)置tableView的contentSize
計(jì)算行數(shù)的公式: 總行數(shù) = (總個(gè)數(shù) + 每行的個(gè)數(shù) - 1) / 每行的個(gè)數(shù)
10.webView加載網(wǎng)頁(yè)
加載網(wǎng)頁(yè)需要從模型中拿URL時(shí),不能在set方法中加載網(wǎng)頁(yè),因?yàn)榇藭r(shí)的webView是空的,set方法先調(diào)用,viewDidLoad后調(diào)用,必須在viewDidLoad里面加載網(wǎng)頁(yè)
11.清除緩存
步驟1.拿到手機(jī)緩存的數(shù)據(jù)大小:
方法1:使用SDWebImage框架中的SDImageCache.h
[SDImageCache sharedImageCache].getSize
注意:只能計(jì)算用SDWebImage下載的圖片所在文件夾的大小
方法2:用文件管理者遍歷拿到所有子文件
//總大小
NSInteger size = 0;
//文件路徑
NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
NSString *file = [cache stringByAppendingPathComponent:@"default"];
//路徑管理者
NSFileManager *manager = [NSFileManager defaultManager];
//遍歷拿到所有的子路徑(包括子路徑的子路徑)
NSArray *subpaths = [manager subpathsAtPath:file];
//遍歷子路徑
for (NSString *subpath in subpaths) {
//根據(jù)子路徑拼接出全路徑
NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];
//文件的所有屬性
NSDictionary *attrs = [manager attributesOfItemAtPath:fullSubpath error:nil];
//將文件的大小加到總大小上
size += [attrs[NSFileSize] integerValue];
}
方法3:NSDirectoryEnumerator(迭代器)遍歷路徑的所有子文件
方法3:
//總大小
NSInteger size = 0;
//文件路徑
NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
NSString *file = [cache stringByAppendingPathComponent:@"default"];
//路徑管理者
NSFileManager *manager = [NSFileManager defaultManager];
//遍歷路徑下的所有子文件
NSDirectoryEnumerator *enumerator = [manager enumeratorAtPath:file];
//遍歷enumerator(類(lèi)似于數(shù)組)
for (NSString *subpath in enumerator) {
//根據(jù)子路徑拼接出全路徑
NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];
//文件的所有屬性
NSDictionary *attrs = [manager attributesOfItemAtPath:fullSubpath error:nil];
//將文件的大小加到總大小上
size += [attrs[NSFileSize] integerValue];
}
步驟2:刪除文件夾
[[NSFileManager defaultManager] removeItemAtPath:@"路徑" error:nil];
*注意點(diǎn)
1.由于遍歷比較耗時(shí),所以要開(kāi)啟新的線程用來(lái)計(jì)算文件的大小
2.為嚴(yán)謹(jǐn)起見(jiàn),要判斷路徑是否存在,而且要判斷路徑是否是文件夾
//判斷是否是文件夾
BOOL isDirectory = NO;
//判斷路徑是否存在
BOOL exists = [manager fileExistsAtPath:@"路徑" isDirectory:&isDirectory];
//如果是文件,就直接計(jì)算大小
if (isDirectory == NO) {
[manager attributesOfItemAtPath:@"路徑" error:nil].fileSize;
}
3.在計(jì)算的時(shí)候應(yīng)該禁止用戶點(diǎn)擊cell,待計(jì)算完畢之后,恢復(fù)點(diǎn)擊
cell.userInteractionEnabled;
12.tableView的行被選中后,馬上彈起(其實(shí)就是取消選中)
調(diào)用選中時(shí)的代理方法(didSelectRowAtIndexPath),在方法內(nèi)部調(diào)用:
[tableView deselectRowAtIndexPath:indexPath animated:YES];
13.不同標(biāo)識(shí)的cell
當(dāng)眾多cell中有個(gè)別特殊的cell時(shí),在循環(huán)利用的時(shí)候會(huì)引起混亂
解決的辦法:可以設(shè)置多個(gè)標(biāo)識(shí),注冊(cè)不同的cell,每次循環(huán)利用的時(shí)候,對(duì)應(yīng)行只加載對(duì)應(yīng)標(biāo)識(shí)的cell
14.正在執(zhí)行動(dòng)畫(huà)的控件移出再回來(lái)后,恢復(fù)動(dòng)畫(huà)
當(dāng)正在執(zhí)行動(dòng)畫(huà)的cell被移出界面,再重新利用回來(lái)后,動(dòng)畫(huà)不再執(zhí)行
解決的辦法:拿到執(zhí)行動(dòng)畫(huà)的控件,再次開(kāi)啟動(dòng)畫(huà)
15.layoutIfNeeded,setNeedsLayout,setNeedsDisplay的區(qū)別**
//重新刷新自己和子控件的所有內(nèi)容(狀態(tài),尺寸)
[testView layoutIfNeeded];
//重新調(diào)用testView的layoutSubviews(重新排布子控件的frame)
[testView setNeedsLayout];
//重新調(diào)用testView的drawRect:方法(重新繪制testView里面的內(nèi)容,一般不包括子控件)
[testView setNeedsDisplay];
- HTTP/1.1協(xié)議中共定義了八種方法(有時(shí)也叫“動(dòng)作”)來(lái)表明Request-URI指定的資源的不同操作
方式:
OPTIONS 返回服務(wù)器針對(duì)特定資源所支持的HTTP請(qǐng)求方法。也可以利用向Web服務(wù)器發(fā)送'*'的請(qǐng)求來(lái)測(cè)試服務(wù)器的功能性?!?HEAD 向服務(wù)器索要與GET請(qǐng)求相一致的響應(yīng),只不過(guò)響應(yīng)體將不會(huì)被返回。這一方法可以在不必傳輸整個(gè)響應(yīng)內(nèi)容的情況下,就可以獲取包含在響應(yīng)消息頭中的元信息?!?GET 向特定的資源發(fā)出請(qǐng)求。注意:GET方法不應(yīng)當(dāng)被用于產(chǎn)生“副作用”的操作中,例如在web app.中。其中一個(gè)原因是GET可能會(huì)被網(wǎng)絡(luò)蜘蛛等隨意訪問(wèn)?!?POST 向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請(qǐng)求體中。POST請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改?!?PUT 向指定資源位置上傳其最新內(nèi)容?!?DELETE 請(qǐng)求服務(wù)器刪除Request-URI所標(biāo)識(shí)的資源?!?TRACE 回顯服務(wù)器收到的請(qǐng)求,主要用于測(cè)試或診斷?!?CONNECT HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。