我有一个函数清除了给定实体中的所有对象,在swift 2中:
private static func clearTable(tableName : String)
{
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
let context : NSManagedObjectContext = appDel.managedObjectContext
let request = appDel.persistentStoreCoordinator
let fetchRequest = NSFetchRequest(entityName: tableName)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try request.executeRequest(deleteRequest, withContext: context)
} catch let error as NSError {
debugPrint(error)
}
}
最近我迁移到了swift 3,现在它看起来像这样:
static func clearTable(_ tableName : String)
{
let appDel = UIApplication.shared.delegate as! AppDelegate
//let context : NSManagedObjectContext = appDel.managedObjectContext
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let request = NSFetchRequest(entityName: tableName)
let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: tableName)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: NSFetchRequest(entityName: tableName))
do {
try request.execute(deleteRequest, with: context)
} catch let error as NSError {
debugPrint(error)
}
}
据我所知,现在我必须声明request
和fetchRequest
之类的
let fetchRequest: NSFetchRequest<SomeEntity> = NSFetchRequest(entityName: "SomeEntity")
问题在于我事先并不了解实体。 swift 3中是否有任何解决方法或反思?我是swift和核心数据的新手,这是获取或删除对象的常用方法吗?
答案 0 :(得分:3)
核心数据中的所有结果类型(包括NSManagedObject
都符合NSFetchRequestResult
,因此请将其用作类型
static func clearTable(_ tableName : String)
{
let appDel = UIApplication.shared.delegate as! AppDelegate
let context = appDel.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: tableName)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
let persistentStoreCoordinator = context.persistentStoreCoordinator!
do {
try persistentStoreCoordinator.execute(deleteRequest, with: context)
} catch let error as NSError {
debugPrint(error)
}
}
这是删除实体所有项目的推荐方法 但是,部署目标必须是≥iOS9 / macOS 10.11。
PS:在Swift 3中,我声明了函数
static func clear(table tableName : String) { ...
答案 1 :(得分:0)
查看此batch delete example以获得更好的方式。
我使用CodeDataStack模式来分离关注点,使代码更加干净。
您可以使用扩展程序使代码更具动态性。您只需调用model.delete()
或Model.deleteAll()
,而不是传递表名。这是其他Web框架中使用的常见模式。
ModelExtension.swift
extension NSManagedObject {
static func context() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.coreData.context()
}
public func delete() {
managedObjectContext?.delete(self)
}
public static func deleteAll() {
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: self.fetchRequest())
do {
try context().execute(batchDeleteRequest)
} catch {
// Error Handling
}
}
}
单元测试:
// My entity name is `Location`
func test_deleteAll() {
_ = fixture.buildTestLocation()
_ = fixture.buildTestLocation()
coreData.saveContext()
Location.deleteAll()
XCTAssertEqual(0, Location.all()?.count)
}
func test_delete() {
let location = fixture.createTestLocation()
XCTAssertEqual(1, Location.all()?.count)
location.delete()
coreData.saveContext()
XCTAssertEqual(0, Location.all()?.count)
}
请注意,Location.all()
是一种自定义方法。