1.// if(0 == [GlobalShare getGlobalShare].user.driverTypes.length)
// {
// onCompletion(nil);
// return;
// }
NSMutableDictionary *dic = [NSMutableDictionary new];
[dic setObject:[GlobalShare getGlobalShare].user.driverTypes forKey:@”driverTypes”];
设置字典时[GlobalShare getGlobalShare].user.driverTypes 为空,导致设置的值为nil,导致崩溃。
2. for (NSDictionary *dic in self.bookOrderArray)
{
int a = [dic[@”id”] intValue];
if (a == [dict[@”orderId”]intValue])
{
// [deletetArray addObject:dic];
[self.bookOrderArray removeObject:dic];
// flag = YES;
// break;
// [self.bookOrderArray removeObject:dic];
// [self.tableView reloadData];
}
}
// for (NSDictionary *dic in deletetArray)
// {
// [self.bookOrderArray removeObject:dic];
// flag = YES;
// // int a = [dic[@”id”] intValue];
// // if (a == [dict[@”orderId”]intValue])
// // {
// // [self.bookOrderArray removeObject:dic];
// // [self.tableView reloadData];
// // }
// }
正遍历数组时删除本可变数组的元素,导致数组个数减少而崩溃。解决访问,先把需要删除的元素放到一个临时删除数组里,然后删除。若一次只删除一个元素只需要直接删除并结束遍历就可以了。
3.
-(void)saveCoordates
{
FLDDLogDebug(@”函数”);
if(-1 != _processingOrderId)
{
NSMutableArray *arr = nil;
NSString *str = nil;
NSString *path = nil;
NSData *data = nil;
NSUInteger count = 0;
path = [Singleton filePath:(NSString *)g_coordatesPath];
if(_canModifyCoordatesFlag && _saveCoordatesFlag)
{
return;
}
_canModifyCoordatesFlag = YES;
_saveCoordatesFlag = YES;
count = _coordates.count;
if(count > 0)
{
if(_saveCoordatesIndex >= count)
{
_saveCoordatesIndex = count;
}
NSMutableArray *coordatesData = [NSMutableArray arrayWithArray:_coordates];
_canModifyCoordatesFlag = NO;
data=[NSData dataWithContentsOfFile : path]; arr = [NSMutableArray arrayWithArray:coordatesData]; NSUInteger i = _saveCoordatesIndex; for (; i < count; i++) { CLLocation* location = arr[i]; if([location isKindOfClass:[CLLocation class]]) { if(0 == str.length) { str = [NSString stringWithFormat:@"%.6f,%.6f", location.coordinate.latitude,location.coordinate.longitude]; } else { str = [NSString stringWithFormat:@"%@\n%.6f,%.6f", str,location.coordinate.latitude,location.coordinate.longitude]; } } } _saveCoordatesIndex = i; } else { _usingCoordatesFlag = NO; } FLDDLogDebug(@"str:%@", str); if(0 == str.length) { return; } else if(0 == data.length) { data = [str dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; [data writeToFile:path atomically:YES]; } else { str = [NSString stringWithFormat:@"\n%@", str]; NSData *dataTemp = [str dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSMutableData *mutableData = [NSMutableData alloc]; [mutableData appendData:data]; [mutableData appendData:(NSData *)dataTemp]; [mutableData writeToFile:path atomically:YES]; } _saveCoordatesFlag = NO; FLDDLogDebug(@"path:%@", path); }
}
一个子线程正访问可变经纬度数组时,定位代理触发经纬数组增加或用户触发删除经纬数组的所有元素导致,数组越界,该例子已经解决。解决方案,操作可变数组时先用NSMutableArray *coordatesData = [NSMutableArray arrayWithArray:_coordates];拷贝出来一份,使用完后替换原来的数组就可以了。当然想更安全些可以设置访问和删除标识。
4.
@property(nonatomic, assign) NSString *cityCode;
-(id)initWithCoder:(NSCoder *)aDecoder
{
if (self=[super init])
{
self.cityCode = [aDecoder decodeObjectForKey:@"cityCode"]; } return self;
}
-(id)initWithDictionary:(NSDictionary*)dic
{
if (self=[super init])
{
self.cityCode = [NSString stringWithFormat:@”%@”,dic[@”cityCode”] ==NULL?@”“:dic[@”cityCode”]];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.cityCode forKey:@"cityCode"];
}
在单例子中用assign声明的字符串变量,在多次便解码时,实际上可能被释放掉,导致内存越界访问,进而编解码时崩溃。
/*******************************************************************
函数: (NSString )getCorrectTelStr : (NSString )string
描述: 字符串格式化处理
调用:
被调用: ((NSString )getTextFieldStr : (NSString )string : (NSString *)textFieldValue
返回值:
其它: 调用者保证字符串为空的情况,减少重复检查参数
********************************************************************/
+ (NSString )getCorrectTelStr : (NSString )string
{
//多一个字符位为了保证能放下增加空格的字符串
NSString *str = [[NSString alloc] initWithString:[NSString stringWithFormat:@”%@%@”, string, @”1”]];
char tel_char = (char )[str UTF8String];
char newTel_char = (char )[string UTF8String];
// char tel_char[12] = {0};
// char newTel_char[14] = {0};
char c;
NSInteger i, j, len;
memset(newTel_char, 0, strlen(newTel_char));
len = strlen(tel_char);
j = 0; for(i = 0; i < len - 1; i++) { c = tel_char[i]; if(c != ' ') { newTel_char[j++] = c; } } memset(tel_char, 0, len); j = 0; for(i = 0; i < strlen(newTel_char); i++) { c = newTel_char[i]; tel_char[j++] = c; if((i == 2) || (i == 6)) { tel_char[j++] = ' '; } } return [[NSString alloc] initWithString:[NSString stringWithFormat:@"%s", tel_char]];
}
NSString和字符数组的转换异常,会死在memset(newTel_char, 0, strlen(newTel_char));这个地方,iphone4s测试出的。
5.
// 下线
- (void)OffLine
{
FLDDLogDebug(@”函数”);
FLDDLogDebug(@”offLine”);
// long long sno = [SingleAsyncSocket sharedInstance].socketThreadSno;
// if(-1 != sno)
// {
// dispatch_sync(dispatch_get_main_queue(), ^{
// // [[SingleAsyncSocket sharedInstance] endSocket];
kill((pid_t)sno, SIGKILL);
// pthread_kill((__bridge pthread_t)([SingleAsyncSocket sharedInstance].socketThread), SIGQUIT);
[[SingleAsyncSocket sharedInstance].socketThread cancel];
// });
//
// }
//
// return;
if([[SingleAsyncSocket sharedInstance] getHitOnOffLineTime] > 0)
{
FLDDLogDebug(@”下线中…”);
[SVProgressHUD showErrorWithStatus:@”下线中…” ];
return;
}
// 发送网络请求 - 下线请求
[SVProgressHUD show];
[[SingleAsyncSocket sharedInstance] socketOffLineClose:^(BOOL successed) { [SVProgressHUD dismiss]; FLDDLogDebug(@"下线成功"); [[SingleObject sharedInstance] setOffLineFlag:YES];
// if(![[SingleObject sharedInstance] getUseBookOrderVoiceArrayFlag])
// {
// [[SingleObject sharedInstance] setUseBookOrderVoiceArrayFlag:YES];
// if(100 != [[SingleObject sharedInstance] getProgress])
// {
// [[SingleObject sharedInstance] stopSpeaking];
// }
// if([[SingleObject sharedInstance] getBookOrderVoiceArray].count > 0)
// {
// [[SingleObject sharedInstance] removeBookOrderVoiceArray];
// }
// [[SingleObject sharedInstance] setUseBookOrderVoiceArrayFlag:NO];
// }
if([SingleObject sharedInstance].playBookingFlag) { [[SingleObject sharedInstance] stopSpeaking]; } else if([SingleObject sharedInstance].playRealOrderFlag) { [[SingleObject sharedInstance] StopVoice]; }
// [[NSNotificationCenter defaultCenter] removeObserver:self name:NEW_ORDER_NOTIFICATION object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:NEW_ORDER_TIMEOUT_NOTIFICATION object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:LOAD_MAP_NOTIFICATION object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:ORDER_FEE_CHANGE_NOTIFICATION object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:PASSENGER_CANCEL_ORDER_NOTIFICATION object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:@”applicationWillEnterForegroundNotification” object:nil];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:OFF_LINE_MAINVIEWCONTROLLER_NOTIFICATION object:nil];
[servicingView removeFromSuperview];
[[Singleton sharedInstance] setLoginOrderStat : LOGIN_ORDER_STATE_OFFLINE];
[self.navigationController popViewControllerAnimated:YES];
// [[SingleObject sharedInstance] setNeedPlayRealOrderFlag:NO];
[[SingleObject sharedInstance] setPlayRealOrderFlag:NO];
// [self.navigationController popToRootViewControllerAnimated:NO];
} onfailCompltion:^(BOOL successed) {
FLDDLogDebug(@”下线失败”);
//非常抱歉,连接出现问题
[SVProgressHUD showErrorWithStatus:@”非常抱歉,连接出现问题” ];
}];
FLDDLogDebug(@”下线”);
}
当一个线程发送了通知,这个地图页面对通知进行了处理,当它回到上一层页面需要显示移除通知,不然再次进入可能收到两个通知,也可能引起崩溃。
6.
- (void)SelectCarTypeWithButton:(UIButton *)sender
{
FLDDLogDebug(@”函数”);
// if (_isSelect[sender.tag - 901])
if (_isSelect[sender.tag])
{
[sender setImage:[UIImage imageNamed:@”接单(未勾选)”] forState:UIControlStateNormal];
NSString *driverTypes = [GlobalShare getGlobalShare].user.driverTypes;
[driverTypesDict removeObjectForKey:[_carTypeDict valueForKey:[NSString stringWithFormat:@”%ld”,(long)sender.tag]]];
if(0 == driverTypes.length)
{
driverTypes = [NSString stringWithFormat:@”%ld”,(long)sender.tag - 900];
}
else
{
NSString *str = nil;
NSArray *values = [driverTypesDict allValues];
for(int i = 0; i < values.count; i++)
{
if(nil == str)
{
str = [NSString stringWithFormat:@”%@”, values[i]];
}
else
{
str = [NSString stringWithFormat:@”%@:%@”, str, values[i]];
}
}
if(str.length > 0) { driverTypes = str; } } [GlobalShare getGlobalShare].user.driverTypes = driverTypes; [[GlobalShare getGlobalShare] saveinfo:([GlobalShare getGlobalShare].user)]; FLDDLogDebug(@"driverTypes:%@", driverTypes); } else { [sender setImage:[UIImage imageNamed:@"接单(勾选)"] forState:UIControlStateNormal]; _currentCarType = [_carTypeDict objectForKey:[NSString stringWithFormat:@"%ld",(long)sender.tag]]; [_selectCarType addObject:_currentCarType]; NSString *driverTypes = [GlobalShare getGlobalShare].user.driverTypes; FLDDLogDebug(@"value: %@", [NSString stringWithFormat:@"%ld",(long)sender.tag - 900]); FLDDLogDebug(@"key: %@", [_carTypeDict valueForKey:[NSString stringWithFormat:@"%ld",(long)sender.tag]]); [driverTypesDict setObject:[NSString stringWithFormat:@"%ld",(long)sender.tag - 900] forKey:[_carTypeDict valueForKey:[NSString stringWithFormat:@"%ld",(long)sender.tag]]]; if((nil == driverTypes) || !([driverTypes isKindOfClass:[NSString class]])) { if(0 != user.serviceType) { driverTypes = [NSString stringWithFormat:@"%d",user.serviceType]; [[GlobalShare getGlobalShare] saveinfo:[GlobalShare getGlobalShare].user]; } else { return; } } if(0 == driverTypes.length) { driverTypes = [NSString stringWithFormat:@"%ld",(long)sender.tag - 900]; } else { NSString *str = nil; NSArray *values = [driverTypesDict allValues]; for(int i = 0; i < values.count; i++) { if(nil == str) { str = [NSString stringWithFormat:@"%@", values[i]]; } else { str = [NSString stringWithFormat:@"%@:%@", str, values[i]]; } } if(str.length > 0) { driverTypes = str; } } [GlobalShare getGlobalShare].user.driverTypes = driverTypes; [[GlobalShare getGlobalShare] saveinfo:([GlobalShare getGlobalShare].user)]; FLDDLogDebug(@"driverTypes:%@", driverTypes); } _isSelect[sender.tag - 901] = !_isSelect[sender.tag - 901];
}
访问数组时下标控制错误或传入的下标超过数组的实际大小,导致数组崩溃,有时候这种数组越界由于ios内部字节对齐等原因有概率出啊线不是立即,而是有时候进入其它页面时崩溃。
7.加载表格时经常出现数组访问或访问空指针,编辑表格后没有结束编译的崩溃。这个就不多说了。