典型崩溃问题集锦

简介: 典型崩溃问题集锦

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


目录
相关文章
|
消息中间件 设计模式 运维
从三万英尺看全链路灰度
从本期开始,我们将通过《全链路灰度:自顶向下的方法》的系列文章,由远及近的剖析全链路灰度全貌,系列文章分为4篇: 《从三万英尺看全链路灰度》、《从三千英尺看全链路灰度》、《从三百英尺看全链路灰度》、《总结篇》。敬请关注!
从三万英尺看全链路灰度
|
19天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8808 25
|
18天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
3466 15
|
17天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2204 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
12天前
|
人工智能 Linux 开发者
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
Codex是OpenAI推出的AI编程智能体,可读取本地项目、理解需求并自动修改代码。支持桌面GUI、命令行(CLI)及VS Code/Cursor插件三种形态,覆盖可视化操作、终端高效开发与编辑器无缝集成场景,助开发者用自然语言驱动编码全流程。(239字)
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
|
18天前
|
云安全 人工智能 安全

热门文章

最新文章