最近一直沒(méi)有更新文章,沒(méi)有別的理由就是自己懶蛇数,回頭想想這幾天忙著撕逼幾天下來(lái)扣字過(guò)萬(wàn)松捉,怎么會(huì)沒(méi)有寫一篇總結(jié)文章的功夫呢栅屏?
這里說(shuō)說(shuō)我在開發(fā)中遇到的2個(gè)由于緩存機(jī)制引起的崩潰問(wèn)題:
一啸箫、在二級(jí)頁(yè)面發(fā)送通知更新一級(jí)頁(yè)面數(shù)據(jù)列表并執(zhí)行返回一級(jí)頁(yè)面時(shí)引起崩潰;
二伞芹、使用UISearchController搜索忘苛,全部數(shù)據(jù)和搜索結(jié)果公用一個(gè)UITableView,在開始搜索的時(shí)候引起崩潰唱较。
問(wèn)題一:
[[NSNotificationCenter defaultCenter]postNotificationName:FINISHARRIVALEQUIP object:nil];
[self.navigationController popViewControllerAnimated:YES];
起初猜測(cè)是發(fā)送通知又多個(gè)頁(yè)面刷新扎唾,數(shù)據(jù)導(dǎo)致主線程堵塞引起崩潰呢,運(yùn)行代碼后南缓,直接發(fā)現(xiàn)是數(shù)組越界引起崩潰胸遇,因?yàn)樵诎l(fā)送通知后,直接請(qǐng)求數(shù)據(jù)會(huì)先清空數(shù)據(jù)源汉形,網(wǎng)絡(luò)請(qǐng)求還沒(méi)有返回?cái)?shù)據(jù)纸镊,此時(shí)剛好執(zhí)行pop返回到當(dāng)前頁(yè)面倍阐,UITableView會(huì)直接從緩存中拿去數(shù)據(jù),但是數(shù)據(jù)源為空逗威。
解決方法:
1峰搪、在返回會(huì)網(wǎng)絡(luò)請(qǐng)求返回?cái)?shù)據(jù)的時(shí)候再清空數(shù)據(jù)源重新賦值
2、清空數(shù)據(jù)源后凯旭,先執(zhí)行 [self.tableView reloadData]刷新列表概耻,再執(zhí)行網(wǎng)絡(luò)請(qǐng)求
問(wèn)題二
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DataSourceItem *item;
if (!_searchController.active) {
item = _dataArray[indexPath.row];
} else {
item = _searchArray[indexPath.row];
}
static NSString *cellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
return cell;
}
點(diǎn)擊搜索的時(shí)候數(shù)據(jù)源切換為_searchArray,但是tableView依然按照_dataArray緩存拿去數(shù)據(jù)罐呼,從而導(dǎo)致崩潰鞠柄。
解決方法:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
[self.tableView reloadData];
}
數(shù)組越界問(wèn)題
上面兩種問(wèn)題最終都是由于數(shù)組越界引起的崩潰,可以使用一下方法判斷是否越界:
if (indexPath.row < _dataArray.count) {
item = [_dataArray objectAtIndex:indexPath.row];
}
不是每次都能記得加數(shù)組越界判斷嫉柴,我們可以使用數(shù)組的分類厌杜,在其中內(nèi)部判斷:
@interface NSArray (Util)
/*!
@method objectAtIndexCheck:
@abstract 檢查是否越界和NSNull如果是返回nil
@result 返回對(duì)象
*/
- (id)objectAtIndexCheck:(NSUInteger)index;
@end
#import "NSArray+Util.h"
@implementation NSArray (Util)
- (id)objectAtIndexCheck:(NSUInteger)index
{
if (index >= [self count]) {
return nil;
}
id value = [self objectAtIndex:index];
if (value == [NSNull null]) {
return nil;
}
return value;
}
@end
總結(jié)
引起的崩潰兩種情況都是數(shù)據(jù)源改變,UITableView并不知道數(shù)據(jù)源改變差凹,還在緩存中通過(guò)IndexPath.row拿取對(duì)應(yīng)數(shù)組中數(shù)據(jù)期奔, 但此時(shí)數(shù)據(jù)源已改變社裆,就可能會(huì)因?yàn)閿?shù)組越界Carsh碰纬,以上兩種情況都可以通過(guò)在改變數(shù)據(jù)源后及時(shí)刷新UITableView來(lái)解決。