首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSDictionary枚举导致"malloc: double free“错误

NSDictionary枚举导致"malloc: double free“错误
EN

Stack Overflow用户
提问于 2014-09-03 02:49:43
回答 1查看 212关注 0票数 0

当使用ns字典enumerateKeysAndObjectsUsingBlock时,我会得到一个双空闲错误:

CnFExhibition_0821(74624,0x114853000) malloc:*对象0x7fe972814fa0错误:双空闲

这主要发生在使用appendFormat:在枚举块中,并不总是发生,而是经常发生。

我最终通过不使用enumerateKeysAndObjectsUsingBlock:来阻止它,但仍然不知道为什么?

当调用这一行( "newData.list“是NSDictionary )时会发生这种情况,

代码语言:javascript
复制
[database updateRow:@"01" inTable:@"Exhibition" setting:newData.list[0] error:nil];

SQLiteHelper.m

代码语言:javascript
复制
-(BOOL)updateRow:(id)rowID inTable:(NSString*)tablename setting:(NSDictionary*)setting error:(NSError *__autoreleasing *)err{
    if ([self checkTableName:tablename error:err]){
        if ([self checkUpdateSetting:setting error:err]) {
            NSMutableString * updateCmd = [sqlCmdUpdateFromTable(tablename) mutableCopy];
            [updateCmd appendString:sqlCmdSetRow(setting)];
            if (rowID) {
                [updateCmd appendString:sqlCmdWhereCondition(@{[self pkOfTable:tablename]:rowID})];
            }
            return [self execCmdStr:updateCmd error:err];
        }else{
        return NO;
        }
    }else{
        return NO;
    }
}

NSString * sqlCmdSetRow(NSDictionary*setting){
    if (setting && setting.count){
        NSMutableString * setCmd = [NSMutableString stringWithString: @" SET "];     
        [[setting copy] enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, id obj, BOOL *stop){
         if ([obj isKindOfClass:[NSString class]]){

//*Mostly crush at this line*
             [setCmd appendFormat:@"%@='%@', ",key,obj]];
         }
         else{
             [setCmd appendFormat:@"%@=%@, ",key,obj];
         }
     }];
    [setCmd deleteCharactersInRange:NSMakeRange(setCmd.length-2, 2)];
    return setCmd;
}
else{
    return nil;
}

}

用下面的代码替换"sqlCmdSetRow“中的枚举,从此不再发生

代码语言:javascript
复制
NSArray * a = [setting allKeys];
for (NSString * s in a) {
    if ([setting[s] isKindOfClass:[NSString class]]){
        [setCmd appendString:[NSString stringWithFormat:@"%@='%@', ",s,setting[s]]];
    }else{
        [setCmd appendFormat:@"%@=%@, ",s,setting[s]];
    }            
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-03 03:13:32

通过使用带有-[NSDictionary enumerateKeysAndObjectsWithOptions:usingBlock:选项的NSEnumerationConcurrent,可以有效地同时调用多线程上同一个NSMutableString对象(setCmd)上的appendString:appendFormat:。这些方法的文档没有提到线程安全,所以它们可能不是线程安全的。你的随机碰撞证明了这一点。

通过更改为for-in循环,您做了正确的事情。现在您只在一个线程上触摸setCmd,没有线程安全问题,崩溃就消失了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25635476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档