2015-11-07 58 views
-1

我想在我的應用程序中使用核心數據。但我想實現一個可以處理數據庫的管理器,但我不知道如何取消上一個獲取請求。我嘗試了一些技巧,但他們沒有工作。在iOS中取消提取請求SWIFT 2

因此,這些都是我的任務:

  • 從核心數據獲取
  • 如果我開始一個新的獲取取消前取
  • 在後臺線程

總結做這些:我如何取消核心數據提取請求?

回答

1

我的建議?從今年的WWDC觀看Advanced NSOperations視頻開始。還要看視頻下的資源和抄本鏈接。許多有關多任務的良好信息。

+0

呀那是唯一一個我沒有嘗試操作隊列,所以你認爲我應該嘗試? 我的意思是我將能夠克服以前的獲取請求並開始一個新的請求? –

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); 
}