如何在没有内存错误的情况下解析iOS中非常长的JSon字符串?

时间:2013-05-08 14:29:19

标签: ios objective-c memory-management memory-leaks

我是iOS新手,我有网络服务,我想下载9000+产品信息,我有一个很长的JSON字符串,所以我在产品下载时收到此错误信息,

  

malloc: * mmap(size = 1978368)失败(错误代码= 12)    错误:无法分配区域   * *在malloc_error_break中设置断点以进行调试

我尝试下载1000以下的产品信息,但效果非常好。我认为,这是记忆问题。

此代码是我项目的一部分。

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

if (temp!=nil && ![temp isEqual:@""]) {
    //basliklar arrayine ilgili tek haberin basligini aktariyoruz.
    //NSLog(@"TEMP=%@",temp);


    NSData *data = [NSJSONSerialization JSONObjectWithData:[temp dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];



    UrunAdi=[data valueForKey:@"UrunAdi"];
    UrunNo=[data valueForKey:@"UrunNo"];
    Koleksiyon=[data valueForKey:@"Koleksiyon"];
    Kompozisyon=[data valueForKey:@"Kompozisyon"];
    GrM=[data valueForKey:@"GrM"];
    URMID=[data valueForKey:@"URMID"];
    En=[data valueForKey:@"En"];
    IslemTipi=[data valueForKey:@"IslemTipi"];
    Dizim=[data valueForKey:@"Dizim"];
    KarteleKodu=[data valueForKey:@"KarteleKodu"];
    Siklik=[data valueForKey:@"Siklik"];
    Euro=[data valueForKey:@"Euro"];
    Dolar=[data valueForKey:@"Dolar"];
    Sterlin=[data valueForKey:@"Sterlin"];
    TL=[data valueForKey:@"TL"];

    [sharedManager  getNewDBConnection];

    if(![temp isEqualToString:@"false"]){

        sqlite3 *contactDB;


        NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docsDir = [dirPaths objectAtIndex:0];
        NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: SQL]];

        NSFileManager *filemgr = [NSFileManager defaultManager];

        if ([filemgr fileExistsAtPath: databasePath ] == YES)
        {
            const char *dbpath = [databasePath UTF8String];

            if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
            {


                NSString *deleteSQL = [NSString stringWithFormat: @"delete from tblKumasBilgi"];

                const char *sql_stmt = [deleteSQL UTF8String];

                if(sqlite3_exec(contactDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK)
                {
                   // NSLog (@"Delete UserData Succesful");
                }
                else
                {
                    NSLog(@"Delete UserData Fail");
                }
                //sqlite3_close(contactDB);
            }
            else
            {
                NSLog(@"Failed to open database");
            }
        }
    }


    if([temp isEqualToString:@"false"]){

         [SVProgressHUD dismiss];

        NSString *warning = NSLocalizedString(@"Warning",nil);
        NSString *check=NSLocalizedString(@"Check Your User Info",nil);
        NSString *okay=NSLocalizedString(@"Ok", nil);

        UIAlertView *alertViewUser = [[UIAlertView alloc] initWithTitle:warning
                                                            message:check
                                                           delegate:self
                                                  cancelButtonTitle:okay
                                                  otherButtonTitles:nil, nil];

        [alertViewUser show];
        alertViewUser.tag=1;
        flag=NO;

    }
    else{

                sqlite3 *contactDB;

                NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                NSString *docsDir = [dirPaths objectAtIndex:0];
                NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: SQL]];

                NSFileManager *filemgr = [NSFileManager defaultManager];

    if ([filemgr fileExistsAtPath: databasePath ] == YES)
    {
        const char *dbpath = [databasePath UTF8String];

        if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
        {


            for (int i = 0; i < [UrunNo count]; i++) {



                NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO tblKumasBilgi (UrunAdi,UrunNo,Koleksiyon,Kompozisyon,Grm,URMID,En,IslemTipi,Dizim,KarteleKodu,Siklik,Euro,Dolar,Sterlin,TL) VALUES ('%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@')", [UrunAdi objectAtIndex:i], [UrunNo objectAtIndex:i], [Koleksiyon objectAtIndex:i], [Kompozisyon objectAtIndex:i], [GrM objectAtIndex:i], [URMID objectAtIndex:i], [En objectAtIndex:i], [IslemTipi objectAtIndex:i],[Dizim objectAtIndex:i],[KarteleKodu objectAtIndex:i], [Siklik objectAtIndex:i],[Euro objectAtIndex:i],[Dolar objectAtIndex:i],[Sterlin objectAtIndex:i], [TL objectAtIndex:i]];

                //NSLog(@"insert =%@",insertSQL);

            const char *sql_stmt = [insertSQL UTF8String];

            if(sqlite3_exec(contactDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK)
            {
                //NSLog (@"INSERT INTO UserData Succesful");
            }
            else
            {
                NSLog(@"INSERT INTO UserData Fail");
            }

        }
        }
        else
        {
            NSLog(@"Failed to open database");
        }
        //sqlite3_close(contactDB);
    }

        [SVProgressHUD dismiss];
        NSString *warning = NSLocalizedString(@"Warning", nil);
        NSString *dataSuccesful=NSLocalizedString(@"Data Download Succesfully", nil);
        NSString *okay=NSLocalizedString(@"Ok", nil);


        UIAlertView *alertViewDownload = [[UIAlertView alloc] initWithTitle:warning
                                                            message:dataSuccesful
                                                           delegate:self
                                                  cancelButtonTitle:okay
                                                  otherButtonTitles:nil, nil];

        [alertViewDownload show];
        alertViewDownload.tag=2;


        flag=NO;
}


tempElement=@"";

} }

感谢您的关注,我很抱歉我的英语不好。

最诚挚的问候。

1 个答案:

答案 0 :(得分:1)

不要一次下载这么多,或者,如果必须,请下载并将JSON保存到磁盘。然后使用一个JSON库,它为您提供一个解析器(如this one)并解析部分JSON。