【问题标题】:NSBlockOperation calling a method inside NSOperationNSBlockOperation 调用 NSOperation 内部的方法
【发布时间】:2013-04-16 10:36:04
【问题描述】:

我有一个问题。 我有以下代码:

NSBlockOperation *op=[NSBlockOperation blockOperationWithBlock:^{

        [[ClassA sharedInstance] someSingletonMethod:params1];
        [ClassB classBMethod:params2];
        [self currentClassMethod:params3];

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"kSNotificationName" object:nil];
        }];
    }];

[self.myOperationQueue addOperation:op];

在块中调用单例方法是否安全?在块中调用类方法是否安全?调用“self”方法是否安全?

我有以下情况。我正在向服务器发送一批请求:

AFHTTPClient *client=[[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
[client registerHTTPOperationClass:[AFJSONRequestOperation class]];
[client enqueueBatchOfHTTPRequestOperations:reqOps progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
    NSLog(@"finished: %i of %i requests", numberOfFinishedOperations, totalNumberOfOperations);
    [[PTDictionaryUpdate sharedInstance] debugPrint:[NSString stringWithFormat:@"finished: %i of %i requests", numberOfFinishedOperations, totalNumberOfOperations]];
} completionBlock:^(NSArray *operations) {
    NSLog(@"operations finished");

这里是我处理响应的方式。 我正在创建操作来处理已完成的请求。

for (int i=0; i<[operations count]; i++)
    {
        AFJSONRequestOperation *operation=[operations objectAtIndex:i];
        if ((operation.error==nil) && (operation.response.statusCode==200))
        {
            id JSON=operation.responseJSON;
            int handleMethodIndex=-1;
            for (int j=0; j<[urls count]; j++)
            {
                if ([operation.request.URL isEqual:[urls objectAtIndex:j]])
                {
                    handleMethodIndex=j;
                };
            };

            switch (handleMethodIndex) {
                case 0:
                {
                    //[self countryUpdate:JSON];

                    NSInvocationOperation *invOp=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(countryUpdate:) object:JSON];
                    [invOp setQueuePriority:NSOperationQueuePriorityLow];
                    [handleJSONOperations addObject:invOp];
                    break;
                }
                case 1:
                {
                    //[self regionsUpdate:JSON];

                    NSInvocationOperation *invOp=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(regionsUpdate:) object:JSON];
                    [invOp setQueuePriority:NSOperationQueuePriorityLow];
                    [handleJSONOperations addObject:invOp];
                    break;
                }
                //.......
          //.......
       }

在我创建了一个数组,该数组将处理(处理和更新数据库)我从服务器提取的 JSON:

NSBlockOperation *op=[NSBlockOperation blockOperationWithBlock:^{

        //first we need to tether countries, regions and cities
        [[PTDataTetherer sharedInstance] tetherCountriesRegionsCitiesInContext:self.updateContext];

        //generating fake agencies
        //[PTFakeAgencyGenerator generateAgenciesInContext:context];

        //generating fake clients
        //[PTFakeClientGenerator generateClientsInContext:context];

        //generating fake reports
        [[PTFakeReportGenerator sharedInstance] generateReportsInContext:self.updateContext];

        //generating fake presentations
        [[PTFakePresentationGenerator sharedInstance] generatePresentationsInContext:self.updateContext];


        //tethering
        [[PTDataTetherer sharedInstance] tetherAgenciesWithOthersInContext:self.updateContext];
        [[PTDataTetherer sharedInstance] tetherClientsWithOthersInContext:self.updateContext];
        [[PTDataTetherer sharedInstance] tetherEventsWithOthersInContext:self.updateContext];
        [[PTDataTetherer sharedInstance] tetherPresentationFoldersWithImagesInContext:self.updateContext];

        [self saveContext];

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"kSynchronizationFinishedNotification" object:nil];
        }];
    }];
    [op setQueuePriority:NSOperationQueuePriorityLow];
    if ([handleJSONOperations count]==0)
    {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"kSynchronizationFinishedNotification" object:nil];
        }];
    }
    else
    {
        [self.serverUpdateQueue addOperation:updateContextCreateOperation];
        [handleJSONOperations addObject:op];
        [self.serverUpdateQueue addOperations:handleJSONOperations waitUntilFinished:NO];
    };

基本上我想以这种方式构造队列: 1.【上下文创建操作】 2. [多个上下文修改操作,将解析从服务器接收到的json并将新/修改对象保存到上下文中] 3. [一些最终方法也会修改上下文,最后会调用 save 方法将更改传播到存储,然后使用 NSManagedObjectContextDidSaveNotifications 到其他上下文]

【问题讨论】:

  • 为什么不安全?您是否遇到过任何问题(异常或崩溃)?

标签: iphone ios objective-c nsoperation nsoperationqueue


【解决方案1】:

在块中调用单例方法是否安全?

这是一个有点板的问题,取决于你在单例方法中的内容。

在块中调用类方法安全吗?

取决于您在方法中执行的操作。根据我的经验和我所做的代码,是的。

调用“self”方法省钱吗?

您将self 的引用传递给块,这可能会导致内存泄漏。

【讨论】:

  • 基本上我想做这样的事情:
  • @RuiAAPeres 你能补充更多关于为什么内存泄漏可能会或可能不会的信息吗?这个边缘在哪里。还有一个问题,这些方法是在那个操作块中执行还是在主线程(队列)中执行?
  • @flinth 取决于 self 是否持有对块的强引用,以及 self 是否在块内被引用。这足以有一个保留周期。阻塞操作取决于执行它的队列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
相关资源
最近更新 更多