典型崩溃问题集锦

简介: 典型崩溃问题集锦

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月前
|
测试技术
ACL 2024:大模型性能掺水严重?北大交出答卷:交互评估+动态出题,死记硬背也没用
【7月更文挑战第8天】北大研究团队推出KIEval框架,针对大语言模型(LLMs)的性能评估进行创新。KIEval采用互动评估和动态出题,通过多轮基于知识的对话测试模型理解和应用能力,旨在减少数据污染影响,挑战死记硬背的评估。然而,该方法可能增加计算需求,且评估结果可能受主观因素影响,不适用于所有类型LLMs。[论文链接:](https://arxiv.org/abs/2402.15043)**
58 24
|
3月前
|
缓存 算法 Java
Linux内核新特性年终大盘点-安卓杀后台现象减少的背后功臣MGLRU算法简介
MGLRU是一种新型内存管理算法,它的出现是为了弥补传统LRU(Least Recently Used)和LFU(Least Frequently Used)算法在缓存替换选择上的不足,LRU和LFU的共同缺点就是在做内存页面替换时,只考虑内存页面在最近一段时间内被访问的次数和最后一次的访问时间,但是一个页面的最近访问次数少或者最近一次的访问时间较早,可能仅仅是因为这个内存页面新近才被创建,属于刚刚完成初始化的年代代页面,它的频繁访问往往会出现在初始化之后的一段时间里,那么这时候就把这种年轻代的页面迁移出去
|
3月前
|
算法 搜索推荐 数据挖掘
掌握程序员之剑:解析常见算法与其在生活和工作中的影响
掌握程序员之剑:解析常见算法与其在生活和工作中的影响
52 1
值得一看!阿里又杀疯了开源内部“M9”级别全彩版分布式实战笔记
系统架构大致经历了单体应用架构→垂直应用架构→分布式架构→SOA架构→微服务架构的演变
|
存储 缓存 测试技术
三十、如何迅速分析出系统I/O的瓶颈在哪里?
最容易想到的是存储空间的使用情况,包括容量、使用量以及剩余空间等。我们通常也称这些为磁盘空间的使用量,因为文件系统的数据最终还是存储在磁盘上。
268 0
J3D在UOS+KIRIN崩溃2:深层原因分析
J3D在UOS+KIRIN崩溃2:深层原因分析
59 0
|
监控 机器人
狩猎者defi夹子机器开发技术原理的分析
过去一年的时间里,DeFi可谓是迅速崛起,发展态势极其迅猛。虽然DeFi尚处于发展早期阶段,但活跃度和参与度都呈指数地在增长。在DeFi中,交易被打包的顺序极大地影响了DeFi的经济利益。例如,在 UniSwap 中,同样两个针对某交易对的买单,先被执行的交易将获得更多代币。若你在一笔买单前买入同样的代币,然后又赶紧卖出,则将毫无风险的获利。
|
算法
信用评分系统运行原理下篇(1)
信用评分系统运行原理下篇(1)
164 0
信用评分系统运行原理下篇(1)
|
机器学习/深度学习 Python
信用评分系统运行原理下篇(3)
信用评分系统运行原理下篇(3)
112 0
信用评分系统运行原理下篇(3)
|
安全 API
[病毒分析]熊猫烧香(下)核心函数部分分析(一)
[病毒分析]熊猫烧香(下)核心函数部分分析
158 0
[病毒分析]熊猫烧香(下)核心函数部分分析(一)
下一篇
云函数