当尝试从 iOS9 中的数据库中获取超过 512 个项目时,该方法挂起。但它适用于 iOS10 及更高版本

The method hangs when trying to fetch more than 512 items from the database in iOS9. But it works for iOS10 and higher

我有一个从数据库提取数据的方法,此方法适用于 iOS 10 及更高版本的所有版本,但对于 iOS 9,如果我尝试调用 fetch 后该方法会挂起要获得超过 512 件商品,请使用代码:

internal func getAll(_ dictId:Int) -> [Word]? {
    let dictFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Words")
    dictFetch.predicate = NSPredicate(format: "dictionary = %@", dictId)
    dictFetch.fetchLimit = 513
        do {
            print("getAll before fetching")
            let res = try self.moc_.fetch(dictFetch) as? [Word]
            print("getAll after fetching")
            return res
        } catch {
            print("error: \(error)")
        }
    return nil
}

如果我将 fetchLimit 设置为 512 或更少,那么这段代码工作正常并且我得到日志:

getAll before fetching
getAll after fetching

但是如果我将 fetchLimit 设置为 513 或更多,那么这段代码会给我这个日志:

getAll before fetching

没有任何错误,只是挂起。

为了测试,我在AppDelegate中只调用了这个方法(项目中没有调用任何其他方法)。同样的结果。我也尝试异步调用它。相同的。 我还更改了 'dictionary' 的输入值并进行排序以检查这是因为 table 中的某个元素。同样,不超过 512 个元素。 Table "Word" 包含 6000 多个项目,在 iOS 10 及更高版本中一切正常。它也没有 'fetchLimit' 挂起。 请给我任何建议。

我找到了解决问题的方法。对于 ios 9 及以下的设备,创建一个从数据库中获取 500 项的循环,直到获取所有必要的数据。 也许有人会派上用场。

    // CHECK VERSION OF IOS
let fetchLimit = NSString(string: UIDevice.current.systemVersion).doubleValue >= 10 ? -1 : 500

internal func getAll(_ dictId:Int) -> [Word]? {
    return getAll(dict, nil, nil)
}

internal func getAll(_ dict:Dictionary,_ aRes:[Word]?,_ lastReg:NSDate?) -> [Word]? {
    let dictFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Words")
    if lastReg != nil {
        dictFetch.predicate = NSPredicate(format: "dictionary = %@ AND registration > %@", dict, lastReg!)
    } else {
        dictFetch.predicate = NSPredicate(format: "dictionary = %@", dictId)
    }
    let sort = NSSortDescriptor(key: "registration", ascending: true)
    dictFetch.sortDescriptors = [sort]
    if fetchLimit > 0 {
        dictFetch.fetchLimit = fetchLimit
    }

    do {
        if let res = try self.moc_.fetch(dictFetch) as? [Word] {
            var aRes_ = aRes != nil ? aRes! + res : res
            if res.count == fetchLimit {
                return self.getAll(dict, aRes_, aRes_[aRes_.count - 1].registration)
            }
            return aRes_
        }
        return aRes
    } catch {
        Titles.l(self, "getAll_, error:  \(error)")
    }
    return nil
}