Iphone 内存分配问题,设备iOS SDK 4.1崩溃(线程0崩溃)

Iphone 内存分配问题,设备iOS SDK 4.1崩溃(线程0崩溃),iphone,memory-leaks,device,nsautoreleasepool,Iphone,Memory Leaks,Device,Nsautoreleasepool,我有两个问题 1) 我的应用程序在设备运行的前几次就可以正常工作。然后在第一个屏幕弹出(选项卡栏)后崩溃。如果我将设备连接到MAC,然后运行设备应用程序,它就会工作(非调试模式) 我检查了崩溃日志,它崩溃了“EXC_BAD_ACCESS(SIGSEGV)”和Thread0。错误是NSAutorelease释放了一个释放的对象 2) 我使用模拟器上的仪器运行应用程序。在这个函数调用中显示了很多漏洞。 下面是一个示例代码。当我使用仪器运行它时,它在“setObject”行上显示泄漏 //类别A-NS

我有两个问题

1) 我的应用程序在设备运行的前几次就可以正常工作。然后在第一个屏幕弹出(选项卡栏)后崩溃。如果我将设备连接到MAC,然后运行设备应用程序,它就会工作(非调试模式)

我检查了崩溃日志,它崩溃了“EXC_BAD_ACCESS(SIGSEGV)”和Thread0。错误是NSAutorelease释放了一个释放的对象

2) 我使用模拟器上的仪器运行应用程序。在这个函数调用中显示了很多漏洞。 下面是一个示例代码。当我使用仪器运行它时,它在“setObject”行上显示泄漏

//类别A-NSObject的子类

+(NSMutableDictionary *)Hello {

 NSMutableDictionary *dctONE = [[NSMutableDictionary alloc]initWithCapacity:0];
 NSMutableArray *arrKeys = [[NSMutableArray alloc] initWithCapacity:0];

    [arrKeys addObject:@"Object1"];
 [arrKeys addObject:@"Object2"];

    [dctONE setObject:[NSString stringWithFormat:@"dsfsdf"] forKey:[arrKeys          objectAtIndex:0]];
 [dctONE setObject:[NSString stringWithFormat:@"dsfsdf"] forKey:[arrKeys objectAtIndex:1]];

    [arrKeys release];
    return dctONE;

}
///B类

-(void)some_Function {
 NSMutableDictionary * dct = [A Hello];   //all declarations are done

 //do stuff with dct
 [dct release];
}
为什么它在“setObject”泄漏??我把一切都放好了,对吗?唯一的问题是[NSString stringWithFormat:]但这是自动释放,对吗

这快把我逼疯了

这两个问题相关吗?? PS:它不会在sim卡上崩溃,奇怪的是,即使我将设备连接到MAC,然后在设备上测试它,它也不会崩溃(不是调试,直接单击设备上的应用程序)

编辑:

-(NSMutableDictionary *) ExecuteDataSet:(NSString *)strQuery
{
    NSMutableDictionary  *dctResult = [[[NSMutableDictionary alloc] init] autorelease];
//  BOOL isSucess = FALSE;

const char *sql = [strQuery UTF8String];
sqlite3_stmt *selectStatement;

//prepare the select statement
int returnValue = sqlite3_prepare_v2(database, sql, -1, &selectStatement, NULL);
if(returnValue == SQLITE_OK)
{
    sqlite3_bind_text(selectStatement, 1, sql, -1, SQLITE_TRANSIENT);
    //loop all the rows returned by the query.
    NSMutableArray *arrColumns = [[NSMutableArray alloc] init];
    for (int i=0; i<sqlite3_column_count(selectStatement); i++) 
    {
        const char *st = sqlite3_column_name(selectStatement, i);
        [arrColumns addObject:[NSString stringWithCString:st encoding:NSUTF8StringEncoding]];
    }
    int intRow =1;
    while(sqlite3_step(selectStatement) == SQLITE_ROW)
    {
        NSMutableDictionary *dctRow = [[NSMutableDictionary alloc] init];
        for (int i=0; i<sqlite3_column_count(selectStatement); i++)                 
        {
            int intValue = 0;
            const char *strValue;
            switch (sqlite3_column_type(selectStatement,i)) 
            {
                case SQLITE_INTEGER:
                    intValue  = (int)sqlite3_column_int(selectStatement, i);
                    [dctRow setObject:[NSString stringWithFormat:@"%d",intValue] forKey:[arrColumns objectAtIndex:i]];                      
                    break;

                case SQLITE_TEXT:
                    strValue = (const char *)sqlite3_column_text(selectStatement, i);
                    [dctRow setObject:[NSString stringWithCString:strValue encoding:NSUTF8StringEncoding] forKey:[arrColumns objectAtIndex:i]];                     
                    break;

                default:
                    strValue = (const char *)sqlite3_column_value(selectStatement, i);
                    [dctRow setObject:[NSString stringWithCString:strValue encoding:NSUTF8StringEncoding] forKey:[arrColumns objectAtIndex:i]];
                    break;
            }

        }
        [dctResult setObject:[dctRow retain] forKey:[NSString stringWithFormat:@"Table%d",intRow]];
        intRow ++;
        [dctRow release];
    }
    [arrColumns release];
}
return dctResult;
-(NSMutableDictionary*)已执行数据集:(NSString*)strQuery
{
NSMutableDictionary*dctResult=[[[NSMutableDictionary alloc]init]autorelease];
//BOOL ISSUCCESS=错误;
const char*sql=[strQuery UTF8String];
sqlite3_stmt*selectStatement;
//准备select语句
int returnValue=sqlite3\u prepare\u v2(数据库,sql,-1,&selectStatement,NULL);
if(returnValue==SQLITE_OK)
{
sqlite3_绑定_文本(selectStatement,1,sql,-1,SQLITE_瞬态);
//循环查询返回的所有行。
NSMutableArray*arrColumns=[[NSMutableArray alloc]init];

对于(int i=0;i而言,泄漏似乎在这条线上:

[dctResult setObject:[dctRow retain] forKey:[NSString stringWithFormat:@"Table%d",intRow]];

setObject
将对它存储的对象调用
retain
,但实际上您是在手动保留它,因此它的retain计数将是2而不是1,当
dctResult
被释放时,它将不会从内存中删除。

您在
+Hello
中做了大量不必要的工作。调试的第一步ing总是为了消除不必要的复杂性。请这样尝试:

+(NSMutableDictionary *)Hello {

     NSMutableDictionary *dctONE = [NSMutableDictionary dictionaryWithObjectsAndKeys:
         @"dsfsdf", @"Object1", @"dsfsdf", @"Object2", nil];

     return dctONE;
}
NSMutableDictionary dictionaryWithObjectsAndKeys
方法采用一个以零结尾的数组,该数组指向object,key,object,key。它返回一个自动删除的NSMutableDictionary对象,这就是您想要返回的对象


在这个世界上没有任何保证,但我几乎可以向你保证方法不会泄漏。

避免返回保留的对象,这是内存泄漏的大门。但我在调用的函数中释放了返回的对象。这还不够好吗?如果没有,我如何返回分配的字典?好的,知道为什么“泄漏”会这样说吗[dctOne setObject:]是一个“retain”,我不会释放它。如果我通过“caller”释放它这没有错吧?还有关于我的第一个问题的任何想法。设备崩溃??根据您的错误,您似乎是在自动释放池中的对象上手动调用
release
,然后,当池调用
release
时,它会触发错误。您可以尝试启用NSZombies来跟踪问题,然后看看是什么解除分配的对象正在收到消息。@pgb这就是问题所在,我已经详细阅读了代码,并且没有释放自动释放池中的任何变量。我唯一感到困惑的地方是“setObject”,就像我使用[stringWithFormat:]后来发布了字典,是因为这个错误吗?@pgb我试过使用NSZombies,但没有发现任何问题。:(@Dan谢谢你的回复,但我在这里发布的Hello函数不是实际的函数。[dctONE setObject:]在从sqlite DB访问数据的while循环中出现。Leaks在该行显示了一个漏洞,所以我发布了一个简化版本。@BK:好的,那么,从我对简化的简化中收集你能得到的信息。特别是使用方便的实例化器返回自动删除的对象。@Dan我按照你说的做了,并返回了一个自动删除对象,但仍然不走运。“泄漏”指出[setObject:]是罪魁祸首。当我不看真实代码时,很难诊断出这一点。您知道[NSString stringWithFormat:@“abcd”]是一个不必要的构造,对吧?是的,我知道。我用它来填充字典,并使用从数据库返回的值-[stringWithFormat:@“%d”,a];等待将放入实际代码。