gpt4 book ai didi

iphone - iOS - 线程不会回到主线程

转载 作者:可可西里 更新时间:2023-11-01 06:21:07 31 4
gpt4 key购买 nike

我的线程有问题。当线程繁忙时,我在 2 个屏幕之间进行了几次 segue 之后。线程不会执行每一行..,当它必须返回主线程时,断点就会消失。有人可以帮我吗?

我在 View 卸载时释放线程。

谢谢,

- (void)fetchFeedDataIntoDocument
{
NSString * labelString = [NSString stringWithFormat:@"Feed Fetcher %@", self.pageTitle];
const char *label = [labelString UTF8String];

self.fetchF = dispatch_queue_create(label, NULL);
dispatch_async(self.fetchF, ^{

NSArray *feeds = [FeedFetcher getDataForJson:self.pageTitle downloadBy:@"up"];

NSDictionary *lastfeed;

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [appDelegate getManagedObjectContext];

if ([feeds count] > 0)
{
lastfeed = [feeds objectAtIndex:0];

[FeedFetcher setLastUpdateIdToCatgorie:self.pageTitle WithId:[lastfeed objectForKey:@"id"] AndPulishDate:[lastfeed objectForKey:@"publish_up"]];
}

for (NSDictionary *feedInfo in feeds) {
[Feed FeedWithInfo:feedInfo InManageObject:context];
}

NSError *error = nil;

[context save:&error];

if (error){
NSLog(@"Error save : %@", error);}

dispatch_async(dispatch_get_main_queue(), ^{
[self setupFetchedResultsController];
[self.tableView reloadData];
[self downloadImagesForFeeds:feeds];
});

});

最佳答案

您正在从创建它的不同线程访问 managedObjectContext。这是核心数据线程规则 #1。

您正在从应用委托(delegate)处获取 MOC。如果它是正常的 Xcode 生成的 MOC,那么它是使用线程限制并发创建的。您甚至不能用它调用 performBlock。您只能从主线程访问该 MOC。时期。其他任何事情充其量都是在玩火。

如果您想在一个单独的线程中完成所有工作,您还需要一个单独的 MOC。像这样(只是输入 - 没有编译)...

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = appDelegate.managedObjectContext;
[moc performBlock:^{
// Go get your remote data and whatever you want to do

// Calling save on this MOC will push the data up into the "main" MOC
// (though it is now in the main MOC it has not been saved to the store).
[moc save:&error];
}];

这会转化为这样的东西......

- (void)fetchFeedDataIntoDocument
{
NSString * labelString = [NSString stringWithFormat:@"Feed Fetcher %@", self.pageTitle];
const char *label = [labelString UTF8String];

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [appDelegate getManagedObjectContext];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = mainContext;
[context performBlock:^{
NSArray *feeds = [FeedFetcher getDataForJson:self.pageTitle downloadBy:@"up"];

NSDictionary *lastfeed;


if ([feeds count] > 0)
{
lastfeed = [feeds objectAtIndex:0];

[FeedFetcher setLastUpdateIdToCatgorie:self.pageTitle WithId:[lastfeed objectForKey:@"id"] AndPulishDate:[lastfeed objectForKey:@"publish_up"]];
}

for (NSDictionary *feedInfo in feeds) {
[Feed FeedWithInfo:feedInfo InManageObject:context];
}

NSError *error = nil;

[context save:&error];

if (error){
NSLog(@"Error save : %@", error);}
DO you really want to continue on error?
dispatch_async(dispatch_get_main_queue(), ^{
// Data has been pushed into main context from the background
// but it still needs to be saved to store...
// Do not forget to perform error handling...
NSError *error = nil;
[mainContext save:&error];
[self setupFetchedResultsController];
[self.tableView reloadData];
[self downloadImagesForFeeds:feeds];
});

});

编辑

Xcode 生成的用于创建 MOC 的代码使用 init,它使用 NSConfinementConcurrencyType。您可以将它替换为 MainConcurrency,不会有任何问题,但会获得一些好处。

在您的应用委托(delegate)文件中,替换...

    __managedObjectContext = [[NSManagedObjectContext alloc] init];

有了这个...

    __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

现在,您的主 MOC 可以是“父类”,您也可以对其调用 performBlock。

关于iphone - iOS - 线程不会回到主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10431195/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com