gpt4 book ai didi

ios - NSManagedObjectContext - FetchRequest 死锁

转载 作者:行者123 更新时间:2023-11-30 13:20:06 28 4
gpt4 key购买 nike

更新说明:我正在使用 Big Nerd Ranch CoreDataStack如果你们想知道的话。

我已经为这个具体问题苦苦挣扎了一段时间了。基本上我试图从 CNContactStore 获取联系人并在自定义 NSOperation 中获取 ContactDetails (NSManagedObject)。

现在我正在尝试在单元测试上运行整个过程。到目前为止,这就是我的代码的样子。

单元测试

func testThatLoaderOperationWorks()
{
var coreDataStack: CoreDataStack?

let semaphore = dispatch_semaphore_create(0);

CoreDataStack.constructSQLiteStack(withModelName: "DataModel") { result in
switch result
{
case .Success(let stack):
coreDataStack = stack
case .Failure(let error):
coreDataStack = nil
print (error)
}


dispatch_semaphore_signal(semaphore);
}

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)


let contactStore = CNContactStore()

let loaderOperation = LoaderOperation.init(withWorkerContext: (coreDataStack?.newChildContext())!, andContactStore: contactStore)
loaderOperation.completionBlock = {
XCTAssert(true)
}

let operationQueue = NSOperationQueue()
operationQueue.maxConcurrentOperationCount = 1
operationQueue.addOperation(loaderOperation)
loaderOperation.waitUntilFinished()
}

操作子类

override func main()
{
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]


var allContainers: [CNContainer] = []
do
{
allContainers = try contactStore.containersMatchingPredicate(nil)
}
catch
{
print("Error fetching containers")
}

var contactList: [CNContact] = []


for container in allContainers
{
let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)

do
{
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
contactList.appendContentsOf(containerResults)
}
catch
{
print("Error fetching results for container")
}
}

self.workerContext.performBlockAndWait
{
let fetchRequest = NSFetchRequest(entityName: "ContactDetails")
do
{
let list = try self.workerContext.executeFetchRequest(fetchRequest)
print("The List: \(list)")
}
catch
{
print(error)
}
}
}

从技术上讲,我想要实现的是能够获取联系人并将其与我从 CoreData 获取的数据进行交叉引用。但是当我运行executeFetchRequest 时发生死锁。我是不是在什么地方做错了什么?

最佳答案

我找到了答案。真的很简单。这个主要原因是我试图让测试方法等待 waitUntilFinished() 直到操作结束,并且在操作本身中我试图让它强制等待 performBlockAndWait() 从而导致死锁。

删除 waitUntilFinished() 并将 performBlockAndWait() 替换为 performBlock()

此外,为了使用异步代码进行单元测试,您必须expectationWithDescription("description")

基本上你的单元测试方法应该如下所示

    let asyncExpectation = expectationWithDescription("longRunningFunction")

.... some stuff here ....


let loaderOperation = LoaderOperation.init(withWorkerContext: (coreDataStack?.newChildContext())!, andContactStore: contactStore)
loaderOperation.completionBlock = {
asyncExpectation.fulfill()
}

let operationQueue = NSOperationQueue()
operationQueue.addOperation(loaderOperation)


self.waitForExpectationsWithTimeout(10) { (error) in
XCTAssertNil(error, "Something went wrong")
XCTAssert(true)
}

关于ios - NSManagedObjectContext - FetchRequest 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37851888/

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