? ? ? ?iOS新手,最近做一個(gè)物流相關(guān)的項(xiàng)目,tableView展示,cell中有一個(gè)“距離”標(biāo)簽需要計(jì)算后展示(百度地圖SDK計(jì)算后代理回調(diào)結(jié)果),數(shù)據(jù)沒(méi)有辦法第一時(shí)間獲得。

? ? ? ?目前想到有兩個(gè)方法解決以上問(wèn)題:
1.得到model數(shù)組 -> 獲取當(dāng)前位置 -> 調(diào)用百度地圖路算方法 -> 每個(gè)model得到結(jié)果 -> talbeView reloadData
2.得到model數(shù)組┬> tableView reloadData └> 獲取當(dāng)前位置 -> 調(diào)用地圖路算方法 -> 每個(gè)model得到結(jié)果 -> 跟新cell對(duì)應(yīng)label
? ? ? ?明顯,方法1的耗時(shí)會(huì)比方法2長(zhǎng),影響用戶體驗(yàn)。方法2的思路關(guān)鍵在于,得到回調(diào)結(jié)果后發(fā)送通知,讓cell更改label,上代碼
Request.m
- (void)addDistanceWithModelData:(id)data myLocation:(CLLocationCoordinate2D)coordinate {
//創(chuàng)建隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
//data 有兩種 根據(jù)類(lèi)型 轉(zhuǎn)換,可以不用理解
NSArray *array = [data isKindOfClass:[TJMOrderData class]] ? ((TJMOrderData *)data).content : ((TJMMyOrderData *)data).data;
//遍歷得到的數(shù)組(中有model),逐個(gè)請(qǐng)求獲得路程
[array enumerateObjectsUsingBlock:^(TJMOrderModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake(obj.consignerLat.doubleValue, obj.consignerLng.doubleValue);
//騎行距離計(jì)算,直接從百度地圖copy來(lái)的
[[TJMLocationService sharedLocationService] calculateRidingDistanceWithDelegate:obj startPoint:coordinate endPoint:endCoordinate];
}];
});
}
Model.m
//代理方法回調(diào) <BMKRouteSearchDelegate>
#pragma mark 返回駕乘搜索結(jié)果
- (void)onGetRidingRouteResult:(BMKRouteSearch *)searcher result:(BMKRidingRouteResult *)result errorCode:(BMKSearchErrorCode)error {
if (error == BMK_SEARCH_NO_ERROR) {
BMKRidingRouteLine *plan = (BMKRidingRouteLine *)[result.routes firstObject];
// 計(jì)算路線方案中的路段數(shù)目
self.getDistance = @(plan.distance / 1000.0);
//發(fā)送通知,通知的名字就是model的內(nèi)存地址(唯一性);
NSString *notiKey = [NSString stringWithFormat:@"%p",self];
[[NSNotificationCenter defaultCenter] postNotificationName:notiKey object:nil userInfo:@{@"model":self}];
}
}
Cell.m
- (void)setViewWithModel:(TJMOrderModel *)model {
if (!model) return;
self.currentModel
//根據(jù)model狀態(tài) 設(shè)置 按鈕 title
/*
//...省略設(shè)置其他view的代碼
*/
//我到取貨點(diǎn)位置
//先置為零
self.myToGetDistanceLabel.text = @"約0.0KM";
if (model.getDistance) {
//如果有就更新label
self.myToGetDistanceLabel.text = [NSString stringWithFormat:@"約%.2fKM",[model.getDistance doubleValue]];
} else {
//如果沒(méi)有,就添加通知
NSString *notiKey = [NSString stringWithFormat:@"%p",_currentModel];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modelDistanceDidGet:) name:notiKey object:nil];
}
//種類(lèi) 尺寸
self.typeNameLabel.text = model.item.itemName;
self.remarkLabel.text = [NSString stringWithFormat:@"%@kg",model.objectWeight];
}
#pragma mark - 通知
- (void)modelDistanceDidGet:(NSNotification *)notification {
TJMOrderModel *model = notification.userInfo[@"model"];
if ([model isEqual:self.currentModel]) {
self.myToGetDistanceLabel.text = [NSString stringWithFormat:@"約%.2fKM",[model.getDistance doubleValue]];
//移除通知
NSString *notiKey = [NSString stringWithFormat:@"%p",model];
[[NSNotificationCenter defaultCenter] removeObserver:self name:notiKey object:nil];
}
}
? ? ? ?距離結(jié)果的回調(diào)在主線程中,cell中的代碼 對(duì) model.getDistance 判斷, 如果不為空,則直接賦值,不添加通知,如果為空,則說(shuō)明回調(diào)還沒(méi)調(diào)用,添加通知,等待回調(diào)后,發(fā)送通知,接收通知后更改結(jié)果,并刪除通知!所以并不會(huì)造成多余的通知!(但是在本文編寫(xiě)過(guò)程中想到,這樣其實(shí)是違反MVC原則的,MVC框架 View 和 Model 不能直接通訊,感覺(jué)目前項(xiàng)目到更好的改進(jìn)辦法,希望大神指點(diǎn))
? ? ? ?第一次寫(xiě)文章,雖然可能并不實(shí)用,但也算是提供了一種思路吧。