典型崩溃问题集锦

简介: 典型崩溃问题集锦

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.加载表格时经常出现数组访问或访问空指针,编辑表格后没有结束编译的崩溃。这个就不多说了。


目录
相关文章
|
1月前
|
数据采集 机器人 计算机视觉
一手训练,多手应用:国防科大提出灵巧手抓取策略迁移新方案
【10月更文挑战第24天】国防科技大学研究人员提出了一种新颖的机器人抓取方法,通过学习统一的策略模型,实现不同灵巧夹具之间的策略迁移。该方法分为两个阶段:与夹具无关的策略模型预测关键点位移,与夹具相关的适配模型将位移转换为关节调整。实验结果显示,该方法在抓取成功率、稳定性和速度方面显著优于基线方法。论文地址:https://arxiv.org/abs/2404.09150
36 1
|
2月前
《从生产者消费者问题到高级解决方案的全方位解读&探究虚假呼唤现象》
《从生产者消费者问题到高级解决方案的全方位解读&探究虚假呼唤现象》
32 0
|
7月前
|
存储 NoSQL 编译器
实战总结|抽丝剥茧,记一次神奇的崩溃
本文详细回放了一个崩溃案例的分析过程。回顾了C++多态和类内存布局、pc指针与芯片异常处理、内存屏障的相关知识。
|
5月前
|
测试技术
ACL 2024:大模型性能掺水严重?北大交出答卷:交互评估+动态出题,死记硬背也没用
【7月更文挑战第8天】北大研究团队推出KIEval框架,针对大语言模型(LLMs)的性能评估进行创新。KIEval采用互动评估和动态出题,通过多轮基于知识的对话测试模型理解和应用能力,旨在减少数据污染影响,挑战死记硬背的评估。然而,该方法可能增加计算需求,且评估结果可能受主观因素影响,不适用于所有类型LLMs。[论文链接:](https://arxiv.org/abs/2402.15043)**
100 24
|
5月前
|
传感器 安全 测试技术
史上最大规模宕机事件的10个重要教训
网络安全公司CrowdStrike旗下的猎鹰传感器(Falcon Sensor)的一次软件更新引发了一场全球危机,导致全球安装有Windows系统计算机出现大规模的蓝屏死机(blue screen of death,即BSOD),结果数千架航班被迫停飞、医院陷入混乱、支付系统崩溃,直接影响了数百万用户,成为历史上最大的 IT 故障。初步统计,宕机事件给财富 500 强企业造成高达 54 亿美元的损失。
|
4月前
|
消息中间件 缓存 前端开发
评论系统如何不崩溃?揭开海量评论背后的技术秘密
小米介绍了一种高效处理海量新闻评论的技术方案。面对突发新闻带来的评论潮,通过采用消息队列异步入库、读写分离以及热点缓存等技术,不仅能有效减轻数据库压力,还能保证用户快速查看最新评论。消息队列如Kafka或RabbitMQ可缓存评论请求,后台异步处理入库,避免数据库过载。读写分离则通过主从数据库架构分散读取负载,配合热点评论的缓存机制进一步提升访问速度。这套架构确保了系统的稳定性和响应速度,适用于高并发的评论处理场景。
68 0
|
运维 监控 算法
基于典型相关分析的故障检测和过程监控算法研究(Matlab代码实现)
基于典型相关分析的故障检测和过程监控算法研究(Matlab代码实现)
131 0
|
机器学习/深度学习 Python
信用评分系统运行原理下篇(3)
信用评分系统运行原理下篇(3)
131 0
信用评分系统运行原理下篇(3)
|
算法
信用评分系统运行原理下篇(1)
信用评分系统运行原理下篇(1)
198 0
信用评分系统运行原理下篇(1)
信用评分系统运行原理上篇(2)
信用评分系统运行原理上篇(2)
143 0
信用评分系统运行原理上篇(2)