在iOS中取消提取请求SWIFT 2

问题描述:

我想在我的应用程序中使用核心数据。但我想实现一个可以处理数据库的管理器,但我不知道如何取消上一个获取请求。我尝试了一些技巧,但他们没有工作。在iOS中取消提取请求SWIFT 2

因此,这些都是我的任务:

  • 从核心数据获取
  • 如果我开始一个新的获取取消前取
  • 在后台线程

总结做这些:我如何取消核心数据提取请求?

我的建议?从今年的WWDC观看Advanced NSOperations视频开始。还要看视频下的资源和抄本链接。许多有关多任务的良好信息。

+0

呀那是唯一一个我没有尝试操作队列,所以你认为我应该尝试? 我的意思是我将能够克服以前的获取请求并开始一个新的请求? –

我理解你的问题更多的是如何取消挂起的核心数据的请求,而不是具体到迅速语法什么。因此,这个例子是在ObjectiveC中,但你可以很容易地翻译它。

一旦正常获取请求已被赋予到核心数据,没有办法将其取消。你必须等待它完成。

你可以,但是,取消了异步获取请求(即那些具有NSAsynchronousFetchRequest启动)。

如果使用NSOperation排队您的操作,你可以取消任何未决的操作,但仍无法抵消任何正在运行。

但是,没有理由对端口的所有代码,以NSOperation的只是这个,因为你可以自己实现类似在很多方面的东西。这是一个选择,因为在NSManagedObjectContext类别...

- (void)performCancelableBlock:(void(^)(void))block { 
    [self performBlock:^{ 
     if (block) { 
      NSUInteger count = [objc_getAssociatedObject(self, @selector(cancelPendingBlocks)) unsignedIntegerValue]; 
      if (count == 0) { 
       block(); 
      } 
     } 
    }]; 
} 

- (void)cancelPendingBlocks { 
    @synchronized(self) { 
     NSUInteger count = [objc_getAssociatedObject(self, _cmd) unsignedIntegerValue]; 
     NSAssert(count+1 > 0, @"count has wrapped; queue is probably hung"); 
     objc_setAssociatedObject(self, _cmd, @(count+1), OBJC_ASSOCIATION_RETAIN); 
    } 
    [self performBlock:^{ 
     @synchronized(self) { 
      NSUInteger count = [objc_getAssociatedObject(self, _cmd) unsignedIntegerValue]; 
      NSAssert(count > 0, @"BUG - cancel count has become unbalanced"); 
      objc_setAssociatedObject(self, _cmd, @(count-1), OBJC_ASSOCIATION_RETAIN); 
     } 
    }]; 
} 

和一个简单的测试来证明它做什么...

- (void)testCancelation { 
    NSManagedObjectContext *moc = [self makeMOC]; 

    // Expect that the original block ran to completion and didn't get "interrupted" 
    XCTestExpectation *origExpectation = [self expectationWithDescription:@"Original block"]; 
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
    [moc performBlock:^{ 
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 
     [origExpectation fulfill]; 
    }]; 
    NSUInteger __block normalBlockCount = 0, cancelBlockCount = 0; 
    for (int i = 0; i < 100; ++i) { 
     [moc performBlock:^{ 
      ++normalBlockCount; 
     }]; 
     [moc performCancelableBlock:^{ 
      ++cancelBlockCount; 
     }]; 
    } 
    [moc cancelPendingBlocks]; 

    // Expect that only blocks in the queue when the cancel request was issued are canceled 
    XCTestExpectation *doneExpectation = [self expectationWithDescription:@"Cancelable block after cancelation"]; 
    [moc performCancelableBlock:^{ 
     [doneExpectation fulfill]; 
    }]; 
    dispatch_semaphore_signal(semaphore); 

    [self waitForExpectationsWithTimeout:10 handler:nil]; 
    XCTAssertEqual(100, normalBlockCount); 
    XCTAssertEqual(0, cancelBlockCount); 
}