草庐IT

ios - 在自己创建的多个线程中执行核心数据操作以节省处理时间

coder 2024-01-13 原文

我已经浏览了很多有关在多线程中执行核心数据操作的信息,但没有运气来解决我的问题。

我的代码是这样的,我必须每十分钟下载一个 csv 文件,其中包含每个 10 秒的条目。这个文件一旦下载就会被解析,内容被保存在数据库中,然后文件被删除,当需要时,我可以从数据库中获取数据。

现在,我现在有一个多月的大量现有内容,随着时间的推移可能会延长到数年,执行将新文件保存到数据库并将对象从核心数据提取到数组中的巨大任务已经使用单线程下载文件会导致大量处理时间。此外,应用中的 View 需要根据所有以前的数据进行调整(它们基本上是数量与时间的关系图)。

我如何在多线程中实现这一目标并优化我的代码处理时间并将 UI 阻塞降至最低?

请注意:在后台线程中执行任务与我无关,因为我无论如何都必须根据总数据显示图表。请提供宝贵意见。

编辑:执行了一些多线程 这是新代码,

- (void) downloadFiles:(NSString *)dataPath{



__block AppDelegate *appD = (AppDelegate *)[[UIApplication sharedApplication] delegate];

backgroundMOC = [[NSManagedObjectContext alloc] init];

[backgroundMOC setPersistentStoreCoordinator:[[appD managedObjectContext] persistentStoreCoordinator]];



if (parsedDetailsDataArrayForCurrentDay) {

    parsedDetailsDataArrayForCurrentDay = nil;

}



if (parsedDetailsDataArrayForCurrentMonth) {

    parsedDetailsDataArrayForCurrentMonth = nil;

}



if (parsedDetailsDataArrayForCurrentYear) {

    parsedDetailsDataArrayForCurrentYear = nil;

}

parsedDetailsDataArrayForCurrentDay = [[NSMutableArray alloc] init];

parsedDetailsDataArrayForCurrentMonth = [[NSMutableArray alloc] init];

parsedDetailsDataArrayForCurrentYear = [[NSMutableArray alloc] init];



dispatch_group_t d_group = dispatch_group_create();





for (NSInteger i = 0; i <= (self.filesListArray.count - 1); i++) {



    NSString *filePathOnPhone = [dataPath stringByAppendingString:[NSString stringWithFormat:@"/%@", [[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"]]];



    NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"ParsedInfiDetails"];



    NSString *nameToGet = [[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"];



    NSLog(@"File Check: %@", nameToGet);

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fileName = %@", nameToGet];

    [fetch setPredicate:predicate];



    NSError *error = nil;



    NSArray *results = [backgroundMOC executeFetchRequest:fetch error:&error];



    NSArray *definedResults = [results copy];

    if(definedResults && (definedResults.count !=0)) {

        NSLog(@"Entities with that name: %@", results);

        @autoreleasepool {



            NSArray *result = [[definedResults sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modDate" ascending:YES]]] copy];



            NSDate *specificDate = [NSDate date];



            NSMutableArray *sortedDateArray = [[NSMutableArray alloc] init];

            NSMutableArray *sortedDateCurrentYearArray = [[NSMutableArray alloc] init];

            NSMutableArray *sortedDateCurrentMonthArray = [[NSMutableArray alloc] init];

            for (int i = 0; i < result.count; i++) {

                NSManagedObject *obj = [result objectAtIndex:i];

                NSDate *objDate = [obj valueForKey:@"modDate"];

                NSCalendar *gregorian = [NSCalendar currentCalendar];



                NSDateComponents *components = [gregorian componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"] fromDate:objDate];

                NSInteger day = [components day];

                NSInteger month = [components month];

                NSInteger year = [components year];



                NSDateComponents *specificComps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:specificDate];

                NSInteger specificDay = [specificComps day];

                NSInteger specificMonth = [specificComps month];

                NSInteger specificYear = [specificComps year];



                if(day == 24){



                }



                if (day == specificDay && month == specificMonth && year == (specificYear-2000)) {

                    [sortedDateArray addObject:obj];

                }



                NSDate *todayDate = [NSDate date];

                NSDateComponents *componentsForToday = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:todayDate];

                NSInteger currentMonth = [componentsForToday month];

                NSInteger currentYear = [componentsForToday year];





                if (year == (currentYear-2000)) {

                    [sortedDateCurrentYearArray addObject:obj];

                }



                if (year == (currentYear -2000) && month == currentMonth) {

                    [sortedDateCurrentMonthArray addObject:obj];

                }

            }



            NSMutableArray *sortedTimedArray = [[NSMutableArray alloc] initWithArray:[sortedDateArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];



            NSMutableArray *sortedTimedCurrentYearArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentYearArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];



            NSMutableArray *sortedTimedCurrentMonthArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentMonthArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];







            [parsedDetailsDataArrayForCurrentDay addObjectsFromArray:sortedTimedArray];

            [parsedDetailsDataArrayForCurrentYear addObjectsFromArray:sortedTimedCurrentYearArray];

            [parsedDetailsDataArrayForCurrentMonth addObjectsFromArray:sortedTimedCurrentMonthArray];

        }

    } else {

        NSLog(@"Error: %@", error);

        NSString *threadName = [NSString stringWithFormat:@"%ld THREAD", (long)i];

        dispatch_queue_t myQueue = dispatch_queue_create([threadName UTF8String], NULL);





        dispatch_group_async(d_group, myQueue, ^{

            NSManagedObjectContext *backgroundMOC1;

            backgroundMOC1 = [[NSManagedObjectContext alloc] init];

            [backgroundMOC1 setPersistentStoreCoordinator:[[appD managedObjectContext] persistentStoreCoordinator]];

            NSLog(@"Entered Thread ");



            BOOL success = [appD.ftpManager downloadFile:[[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"] toDirectory:[NSURL URLWithString:dataPath] fromServer:srv];



            if (success) {

//                dispatch_group_async(d_group, myQueue, ^{

                NSMutableDictionary *dict = [appD.ftpManager progress];

                NSString *filePath = [dataPath stringByAppendingString:[NSString stringWithFormat:@"/%@", [[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"]]];



                CHCSVParser *parser = [[CHCSVParser alloc] initWithContentsOfCSVURL:[NSURL fileURLWithPath:filePath]];

                [parser parse];

                NSMutableArray *currentFileComponentsArray = [NSArray arrayWithContentsOfCSVURL:[NSURL fileURLWithPath:filePath]];

                NSMutableArray *parsedDetailsEntitiesArray = [[NSMutableArray alloc] init];

                for (int j = 1; j <= (currentFileComponentsArray.count-1); j++) {





                    NSArray *detailsArray = [currentFileComponentsArray objectAtIndex:j];

                    if (!(detailsArray.count < 32)) {

                        NSManagedObject *parsedDetails = [NSEntityDescription

                                                          insertNewObjectForEntityForName:@"ParsedInfiDetails"

                                                          inManagedObjectContext:[appD managedObjectContext]];

                        NSString *totalDateString = [NSString stringWithFormat:@"%@ %@", [detailsArray objectAtIndex:0], [detailsArray objectAtIndex:1]];

                        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

                        dateFormatter.dateFormat = @"dd/MM/yyyy HH:mm:ss";

                        NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];

                        [dateFormatter setTimeZone:gmt];

                        NSDate *startDate = [dateFormatter dateFromString:totalDateString];

                        [parsedDetails setValue:startDate forKey:@"modDate"];

                        [parsedDetails setValue:startDate forKey:@"modTime"];

                        ———————————————————————PERFORM PARSEDDETAILS STATEMENTS----------------





                        NSError *error;



                        NSLog(@"Saved File in Database: %@", [[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"]);

                        NSLog(@"Saved thread");

                        if (![backgroundMOC1 save:&error]) {

                            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);

                        }

                        else{

                            if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

                                //if the download fails, we try to delete the empty file created by the stream.

                                [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];

                                //when data is stored in coredata remove the downloaded file.

                            }

                            [parsedDetailsEntitiesArray addObject:parsedDetails];



                        }



                    }





                }

                NSSet *set = [[NSSet alloc] initWithArray:parsedDetailsEntitiesArray];

                [self.relevantInverId setValue:set forKey:@"infiDetails"];



                NSDate *specificDate = [NSDate date];

                @autoreleasepool {

                    NSMutableArray *sortedDateArray = [[NSMutableArray alloc] init];

                    NSMutableArray *sortedDateCurrentYearArray = [[NSMutableArray alloc] init];

                    NSMutableArray *sortedDateCurrentMonthArray = [[NSMutableArray alloc] init];



                    for (int i = 0; i < parsedDetailsEntitiesArray.count; i++) {

                        NSManagedObject *obj = [parsedDetailsEntitiesArray objectAtIndex:i];

                        NSDate *objDate = [obj valueForKey:@"modDate"];



                        NSCalendar *gregorian = [NSCalendar currentCalendar];



                        NSDateComponents *components = [gregorian componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"] fromDate:objDate];

                        NSInteger day = [components day];

                        NSInteger month = [components month];

                        NSInteger year = [components year];



                        NSDateComponents *specificComps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:specificDate];

                        NSInteger specificDay = [specificComps day];

                        NSInteger specificMonth = [specificComps month];

                        NSInteger specificYear = [specificComps year];



                        if(day == 24){





                        }

                        if (day == specificDay && month == specificMonth && year == (specificYear-2000)) {

                            [sortedDateArray addObject:obj];

                        }



                        NSDate *todayDate = [NSDate date];

                        NSDateComponents *componentsForToday = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:todayDate];

                        NSInteger currentMonth = [componentsForToday month];

                        NSInteger currentYear = [componentsForToday year];





                        if (year == (currentYear-2000)) {

                            [sortedDateCurrentYearArray addObject:obj];

                        }



                        if (year == (currentYear-2000) && month == currentMonth) {

                            [sortedDateCurrentMonthArray addObject:obj];

                        }



                    }



                    NSMutableArray *sortedTimedArray = [[NSMutableArray alloc] initWithArray:[sortedDateArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];



                    [parsedDetailsDataArrayForCurrentDay addObjectsFromArray:sortedTimedArray];





                    NSMutableArray *sortedTimedCurrentYearArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentYearArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];



                    NSMutableArray *sortedTimedCurrentMonthArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentMonthArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];







                    [parsedDetailsDataArrayForCurrentYear addObjectsFromArray:sortedTimedCurrentYearArray];

                    [parsedDetailsDataArrayForCurrentMonth addObjectsFromArray:sortedTimedCurrentMonthArray];

                }




//                                    });



            }



        });



    }







    BOOL isFileAlreadyPresent = [[NSFileManager defaultManager] fileExistsAtPath:filePathOnPhone];





}



NSMutableArray *sortedParsedDetailsArrayForCurrentDay = [[NSMutableArray alloc] initWithArray:[parsedDetailsDataArrayForCurrentDay sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"modTime" ascending:YES]]]];



NSDate *startDate ;

NSDate *endaDate;





dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{

    dispatch_async(dispatch_get_main_queue(), ^{

        [self stopLogoSpin];

        [hud dismiss];



    });

    NSLog(@"All background tasks are done!!");

});


}

现在,日志 @"Entered Thread "在日志中可见,但 @"Saved File in Database: %@", [[self.filesListArray objectAtIndex:i] 和 @"Saved thread"未被调用。

此外,

BOOL success = [appD.ftpManager downloadFile:[[self.filesListArray objectAtIndex:i] objectForKey:@"kCFFTPResourceName"] toDirectory:[NSURL URLWithString:dataPath] fromServer:srv];

在下载方法中使用单独的线程帮助下载文件。 取消下面的评论会有帮助吗?

    //                dispatch_group_async(d_group, myQueue, ^{

主线程是有意等待的,但下面的这个 block 也从未被调用:

dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self stopLogoSpin];
        [radialHUD dismiss];

    });
    NSLog(@"All background tasks are done!!");
});

请指教以上问题的修改和解决方法。

最佳答案

通过将循环中不需要的所有内容移到外部并使用 GCD 执行循环操作来优化代码。

 dispatch_queue_t myOwnQueue = dispatch_queue_create([@"MyOwnQueue" UTF8String], NULL);

dispatch_apply(self.filesListArray.count, myOwnQueue, ^(size_t i) {   });

这导致时间减少了一半。然而,还需要进一步优化。

关于ios - 在自己创建的多个线程中执行核心数据操作以节省处理时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32393589/

有关ios - 在自己创建的多个线程中执行核心数据操作以节省处理时间的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  4. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  5. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  6. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

随机推荐