gpt4 book ai didi

ios - NSOperation 执行失败

转载 作者:行者123 更新时间:2023-12-01 18:13:51 25 4
gpt4 key购买 nike

  • 我对 NSOperations 有疑问。一切正常,但有时(我不知道为什么)操作 block 被简单地跳过。我错过了什么吗?操作怎么可能不是 NSLogging “输入操作”?以下是 viewDidLoad 中的一些代码:
    //I'm using weakOperation in order to make [self.queue cancelAllOperation] method when viewWillDisappear

    NSBlockOperation* operation = [[NSBlockOperation alloc] init];
    __weak NSBlockOperation* weakOperation = operation;

    NSString *session=@"";
    @try{
    session = [self getSessionId];//getting data from CoreData

    }@catch(NSException *e)
    {
    NSLog(@"EXCEPTION WITH SESSION");
    }

    weakOperation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"operation entered");
    [self downloadJSONArray]; //doing some connection downloading and using session
    [self downloadImages]; //downloading images from urls from JSONs
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self refresh]; //update mainThread
    }
    }

    [self.queue addOperation:weakOperation];

    可以跳过此 block 的情况可能是什么?
  • 在 iOS 中创建的线程数是否最大?

  • 编辑 : 嘿,我找到了为什么会发生这种情况 - 当很多应用程序在后台运行并且 iOS 没有资源来排队另一个线程时它只是跳过它,在这种情况下如何表现?

    最佳答案

    您正在分配一个新的 NSBlockOperation为弱变量。每当您将新对象分配给弱变量时,您就有可能立即释放它。

    如果您需要对该操作的弱引用,则首先将对象分配给某个局部变量,然后获取该对象的弱引用:

    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"operation entered");
    [self downloadJSONArray]; //doing some connection downloading and using session
    [self downloadImages]; //downloading images from urls from JSONs
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self refresh]; //update mainThread
    }
    }

    __weak NSBlockOperation* weakOperation = operation;

    [self.queue addOperation:weakOperation];

    但是,就方法而言, weakOperation是不必要的。您通常只需要弱引用来避免强引用循环。但是目前没有这样的循环,所以你可以这样做:
    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"operation entered");
    [self downloadJSONArray]; //doing some connection downloading and using session
    [self downloadImages]; //downloading images from urls from JSONs
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self refresh]; //update mainThread
    }
    }

    [self.queue addOperation:operation];

    查看您的代码注释,您说“我正在使用 weakOperation 以便在 [self.queue cancelAllOperation] 时制作 viewWillDisappear 方法”。使用 weakOperation像这样不会完成你想要的,因为你的操作没有检查它是否被取消,因此当 NSOperationQueue 时它不会响应试图取消它。

    如果您想这样做,那么您的 weakOperation 的变体模式可能很有用,但与其使用 weakOperation要将其添加到队列中,您可以使用 block 内的弱引用来检查操作是否被取消(并且您希望 block 中的弱引用避免 block 保留操作本身,从而导致强引用循环)。另一个关键观察是,与其创建一个新的 NSBlockOperation ,只需在您创建的原始操作中添加一个执行 block :
    NSBlockOperation* operation = [[NSBlockOperation alloc] init];
    __weak NSBlockOperation* weakOperation = operation;

    [operation addExecutionBlock:^{
    NSLog(@"operation entered");

    if ([weakOperation isCancelled]) return;

    [self downloadJSONArray]; //doing some connection downloading and using session

    if ([weakOperation isCancelled]) return;

    [self downloadImages]; //downloading images from urls from JSONs

    if ([weakOperation isCancelled]) return;

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self refresh]; //update mainThread
    }];
    }];

    [self.queue addOperation:operation];

    显然,如果操作在 downloadJSONArraydownloadImages ,它不会响应取消事件,直到它从这些方法返回。如果您希望此操作对取消事件做出合理快速的响应,您还必须使用这些方法检查取消状态。

    在回答您的第二个问题时,是的,有最大线程数,但这是一个相当大的数字,并且在线程数成为问题之前还有其他因素起作用。约束因素可能是 downloadImages方法(因为您只能有 5 个并发下载请求)。即使这不是问题,您也希望限制并发操作的数量,以减轻应用程序的峰值内存使用量。如果涉及任何网络操作,您通常需要执行以下操作:
    self.queue.maxConcurrentOperationCount = 4;  // or 5

    这样,您可以最大限度地减少您正在使用的有限系统资源(包括线程)的数量。

    顺便说一句,我假设 downloadJSONArraydownloadImages是同步方法。如果它们正在执行异步网络请求,您可能需要考虑进一步重构代码以确保操作不会过早完成(例如,将其包装在并发的 NSOperation 子类中或将这些方法更改为同步运行)。

    关于ios - NSOperation 执行失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24891343/

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