Temel Veriler'de depolanan tüm girdileri silmenin bir yolunu biliyor musunuz? Şemam aynı kalmalı; Sadece boş olarak sıfırlamak istiyorum.
Düzenle
Bir kullanıcı aslında bir reset
düğmeye basmak böylece bunu programlı olarak yapmak için arıyorum .
Temel Veriler'de depolanan tüm girdileri silmenin bir yolunu biliyor musunuz? Şemam aynı kalmalı; Sadece boş olarak sıfırlamak istiyorum.
Düzenle
Bir kullanıcı aslında bir reset
düğmeye basmak böylece bunu programlı olarak yapmak için arıyorum .
Yanıtlar:
Yine de NSFileManager: removeItemAtPath :: yöntemini kullanarak dosyayı programlı olarak silebilirsiniz.
NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
Ardından, düzgün bir şekilde yeniden oluşturulduğundan emin olmak için kalıcı mağazayı geri ekleyin.
Her varlık üzerinden yineleme yapmanın programlı yolu hem daha yavaş hem de hataya yatkındır. Bunu bu şekilde kullanmanın amacı, bazı varlıkları silmek, diğerlerini silmek istemenizdir. Ancak, yine de referans bütünlüğünü koruduğunuzdan emin olmanız gerekir, aksi takdirde değişikliklerinizi devam ettiremezsiniz.
Mağazayı kaldırmak ve yeniden oluşturmak hem hızlı hem de güvenlidir ve kesinlikle çalışma zamanında programlanabilir.
İOS5 + için güncelleme
İOS 5 ve OS X 10.7'de harici ikili depolamanın (harici kayıt dosyasında ExExBBDataDataStorage veya Store'a izin verir) piyasaya sürülmesiyle, storeURL'lerin işaret ettiği dosyaları silmek yeterli değildir. Harici kayıt dosyalarını geride bırakacaksınız. Bu harici kayıt dosyalarının adlandırma düzeni herkese açık olmadığından henüz evrensel bir çözümüm yok. - an0 8 Mayıs '23 at 23:00
SQLite dosyasını silebilirsiniz - ancak tabloları bir işlevle ayrı ayrı temizleyerek yapmayı seçiyorum:
- (void) deleteAllObjects: (NSString *) entityDescription {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
for (NSManagedObject *managedObject in items) {
[_managedObjectContext deleteObject:managedObject];
DLog(@"%@ object deleted",entityDescription);
}
if (![_managedObjectContext save:&error]) {
DLog(@"Error deleting %@ - error:%@",entityDescription,error);
}
}
Tabloyu tabloya göre yapmamın nedeni, tablonun içeriğini silmenin mantıklı olduğunu ve saklamak istediğim veri olmadığını programlama yaparken onaylamamı sağlıyor.
Bunu yapmak sadece dosyayı silmekten çok daha yavaş olacaktır ve eğer bu yöntem çok uzun sürerse bir dosya silme işlemine geçeceğim.
NSBatchDeleteRequest
Varlıktaki tüm nesneleri belleğe yüklemek veya yinelemek zorunda kalmadan silmek için kullanın .
// create the delete request for the specified entity
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
// get reference to the persistent container
let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
// perform the delete
do {
try persistentContainer.viewContext.execute(deleteRequest)
} catch let error as NSError {
print(error)
}
Bu kod iOS 10 ve Swift 3 için güncellendi. İOS 9'u desteklemeniz gerekiyorsa, bu soruya bakın .
Kaynaklar:
moc.performBlockAndWait({ () -> Void in
... içine yerleştirirdim })
.
clearStores
Her mağazadan geçen ve hem koordinatörden hem de dosya sisteminden silinen bir yöntem yazdım (hata işleme bir kenara bırakıldı):
NSArray *stores = [persistentStoreCoordinator persistentStores];
for(NSPersistentStore *store in stores) {
[persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
Bu yöntem, coreDataHelper
(diğer şeylerin yanı sıra) nil olduğunda persistentStore oluşturmaya özen gösteren bir sınıfın içindedir .
Bir düğme üzerindeki temel verilerden tüm verileri HomeViewController sınıfındaki olaydan kaldırırım: Bu makale bana katkıda bulunacağımı düşündüm.
-(IBAction)buttonReset:(id)sender
{
NSLog(@"buttonReset Pressed");
//Erase the persistent store from coordinator and also file manager.
NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
NSError *error = nil;
NSURL *storeURL = store.URL;
[self.persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
NSLog(@"Data Reset");
//Make new persistent store for future saves (Taken From Above Answer)
if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
}
Self.persistentStoreCoordinator öğesini çağırmak için Home View Controller'da bir özellik beyan ettiğimi unutmayın. (Kaydetme ve yükleme için kullandığım manageObjectContext hakkında endişelenmeyin.)
@property (nonatomic, retain) NSManagedObjectContext * managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator * persistentStoreCoordinator;
Sonra hemen bir HomeViewController oluşturma AppDelegate ApplicationDidFinishLaunching içinde ben var:
homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;
MagicalRecord bunu çok kolaylaştırıyor.
[MyCoreDataObject MR_truncateAll];
MR_truncateAll
?
iOS9 +, Swift 2
Tüm varlıklardaki tüm nesneleri sil
func clearCoreDataStore() {
let entities = managedObjectModel.entities
for entity in entities {
let fetchRequest = NSFetchRequest(entityName: entity.name!)
let deleteReqest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.executeRequest(deleteReqest)
} catch {
print(error)
}
}
}
[Daha yeni yanıtlar isteyen bir lütuf karşısında geç cevap]
Önceki cevaplara baktığımızda,
Ancak, işe yarayan kalıcı mağazayı kaldırmak için farklı, benzer bir yaklaşım var. Anahtar, kalıcı mağaza dosyanızı başka bir şey içermeyen kendi alt dizinine koymaktır. Yalnızca belge dizinine (veya herhangi bir yere) yapıştırmayın, yalnızca kalıcı mağaza için yeni bir alt dizin oluşturun. Bu dizinin içeriği kalıcı saklama dosyası, günlük dosyaları ve harici ikili dosyalar olur. Tüm veri deposunu tıklatmak istiyorsanız, bu dizini silin, hepsi kaybolur.
Kalıcı mağazanızı kurarken böyle bir şey yaparsınız:
NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
withIntermediateDirectories:NO
attributes:nil
error:nil]) {
NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
// continue with storeURL as usual...
}
Sonra mağazayı kaldırmak istediğinizde,
[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];
Bu, hem özel alt dizini hem de içindeki tüm Temel Veri dosyalarını yinelemeli olarak kaldırır.
Bu yalnızca kalıcı deponuzu diğer önemli verilerle aynı klasörde yoksa çalışır . Muhtemelen içinde başka yararlı şeyler olan belgeler dizini gibi. Bu senin durum varsa, o dosyalara bakarak aynı etkiyi alabilir do tutmak istiyoruz ve her şeyi kaldırarak. Gibi bir şey:
NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
// Look at docsDirectoryItem. If it's something you want to keep, do nothing.
// If it's something you don't recognize, remove it.
}
Bu yaklaşım hataya meyilli olabilir . Saklamak istediğiniz her dosyayı bildiğinizden kesinlikle emin olmalısınız , aksi takdirde önemli verileri kaldırabilirsiniz. Öte yandan, harici ikili dosyaları saklamak için kullanılan dosya / dizin adını gerçekten bilmeden kaldırabilirsiniz.
İşte Temel Verileri temizlemek için kombine çözüm.
- (void)deleteAllObjectsInCoreData
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
}
for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
}
if (![self.managedObjectContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
}
}
}
Tüm nesneleri silmek ve yedekleme dosyalarını silmek istemiyorsanız, aşağıdaki yöntemleri kullanabilirsiniz:
- (void)deleteAllObjectsInContext:(NSManagedObjectContext *)context
usingModel:(NSManagedObjectModel *)model
{
NSArray *entities = model.entities;
for (NSEntityDescription *entityDescription in entities) {
[self deleteAllObjectsWithEntityName:entityDescription.name
inContext:context];
}
}
- (void)deleteAllObjectsWithEntityName:(NSString *)entityName
inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:entityName];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
NSLog(@"Deleted %@", entityName);
}
}
Çok yavaş olabileceğine dikkat edin (nesne grafiğinizde kaç nesne olduğuna bağlıdır).
Tüm nesneleri silme yoluna gitmek istiyorsanız (Çekirdek Veri yığınını yıkmaktan çok daha basit, ancak daha az performans), bu daha iyi bir uygulamadır:
- (void)deleteAllManagedObjectsInModel:(NSManagedObjectModel *)managedObjectModel context:(NSManagedObjectContext *)managedObjectContext
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[managedObjectContext performBlockAndWait:^{
for (NSEntityDescription *entity in managedObjectModel) {
NSFetchRequest *fetchRequest = [NSFetchRequest new];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:NO];
NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *managedObject in objects) {
[managedObjectContext deleteObject:managedObject];
}
}
[managedObjectContext save:nil];
}];
}];
[operation setCompletionBlock:^{
// Do stuff once the truncation is complete
}];
[operation start];
}
Bu uygulama NSOperation
, ana iş parçacığının silinmesini gerçekleştirmek ve tamamlandığında bilgilendirmek için kullanılır. Durumu ana iş parçacığına geri döndürmek için tamamlama bloğunda bir bildirim veya başka bir şey yayınlamak isteyebilirsiniz.
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
Bu yöntemi kullanmak için illâ hatayı alıyorum:Can only use -performBlock: on an NSManagedObjectContext that was created with a queue.
iOS 10 + Swift 3 çözümü:
func clearCoreDataStore() {
let delegate = UIApplication.shared.delegate as! AppDelegate
let context = delegate.persistentContainer.viewContext
for i in 0...delegate.persistentContainer.managedObjectModel.entities.count-1 {
let entity = delegate.persistentContainer.managedObjectModel.entities[i]
do {
let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
let deleterequest = NSBatchDeleteRequest(fetchRequest: query)
try context.execute(deleterequest)
try context.save()
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
abort()
}
}
}
Tüm temel veri varlıkları üzerinden yinelenir ve bunları temizler
Gönderi için teşekkürler. Onu takip ettim ve benim için çalıştı. Ama cevapların hiçbirinde bahsedilmeyen başka bir sorunum vardı. Bu yüzden sadece ben olup olmadığımdan emin değilim.
Her neyse, burada sorunu ve çözüm yolumu göndereceğimi düşündüm.
Ben veritabanında birkaç kayıt vardı, ben db yeni veri yazmadan önce her şeyi temiz temizlemek istedim, bu yüzden dahil her şeyi yaptım
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
ve daha sonra managedObjectContext
veritabanına erişmek için kullanılır (şimdiye kadar boş olması gerekiyordu), bir şekilde veriler hala oradaydı. Sorun giderme Bir süre sonra ben sıfırlamak gerekir bulundu managedObjectContext
, managedObject
, managedObjectModel
ve
persistentStoreCoordinator
ben kullanmadan önce, managedObjectContext
dabase erişmek için. Şimdi yazmak için temiz bir veritabanı var.
İşte AppDelegate'in kendine daha az çağrı ve en yüksek puanlı yanıtın dışında kalan son kod bitiyle biraz basitleştirilmiş bir sürüm. Ayrıca "Nesne kalıcı mağaza bu NSManagedObjectContext koordinatörü ulaşılabilir değildir" bir hata alıyordu bu yüzden sadece geri eklemek için gerekli.
NSPersistentStoreCoordinator *storeCoordinator = [self persistentStoreCoordinator];
NSPersistentStore *store = [[storeCoordinator persistentStores] lastObject];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dataModel"];
NSError *error;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
if (storeCoordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:storeCoordinator];
}
hızlı çözüm:
class func deleteAllManagedObjects() {
let modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "mom")
let mom = NSManagedObjectModel(contentsOfURL: modelURL)
for entityName in mom.entitiesByName.keys {
let fr = NSFetchRequest(entityName: entityName as String)
let a = Utility.managedObjectContext().executeFetchRequest(fr, error: nil) as [NSManagedObject]
for mo in a {
Utility.managedObjectContext().deleteObject(mo)
}
}
Utility.managedObjectContext().save(nil)
}
let modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "momd")!
Başka bir yerde aramayı kaydetmek için hızlı bir referans olarak - kalıcı mağazayı sildikten sonra yeniden oluşturmak aşağıdakilerle yapılabilir:
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
Bu soruya birkaç iyi cevap. İşte güzel bir özlü. İlk iki satır sqlite veritabanını siler. Ardından for: döngüsü, yönetilenObjectContext belleğindeki nesneleri siler.
NSURL *storeURL = [[(FXYAppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory] URLByAppendingPathComponent:@"AppName.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
for (NSManagedObject *ct in [self.managedObjectContext registeredObjects]) {
[self.managedObjectContext deleteObject:ct];
}
ayrıca tüm varlık adlarını bulabilir ve ada göre silebilirsiniz. Daha uzun bir versiyon ama iyi çalışıyor, bu şekilde kalıcılık deposu ile çalışmak zorunda değilsiniz
- (void)clearCoreData
{
NSError *error;
NSEntityDescription *des = [NSEntityDescription entityForName:@"Any_Entity_Name" inManagedObjectContext:_managedObjectContext];
NSManagedObjectModel *model = [des managedObjectModel];
NSArray *entityNames = [[model entities] valueForKey:@"name"];
for (NSString *entityName in entityNames){
NSFetchRequest *deleteAll = [NSFetchRequest fetchRequestWithEntityName:entityName];
NSArray *matches = [self.database.managedObjectContext executeFetchRequest:deleteAll error:&error];
}
if (matches.count > 0){
for (id obj in matches){
[_managedObjectContext deleteObject:obj];
}
[self.database.managedObjectContext save:&error];
}
}
"Any_Entity_Name" için yalnızca kuruluşunuzun adlarından herhangi birini verin, yalnızca varlıklarınızın içerisindeki varlık açıklamasını bulmamız gerekir. ValueForKey @ "name" tüm varlık adlarını döndürür. Son olarak, kaydetmeyi unutmayın.
Kabul edilen cevap, URL'nin NSFileManager tarafından kaldırılmasıyla doğrudur, ancak iOS 5+ düzenlemesinde belirtildiği gibi, kalıcı mağaza yalnızca bir dosyayla temsil edilmez. SQLite mağazası için * .sqlite, * .sqlite-shm ve * .sqlite-wal ... neyse ki iOS 7+'den beri yöntemi kullanabiliriz
[NSPersistentStoreCoordinator + removeUbiquitousContentAndPersistentStoreAtURL: seçenekler: hata:]
kaldırmaya dikkat etmek için, kod böyle bir şey olmalıdır:
NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSString *storeName = ...;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL.path options:@{NSPersistentStoreUbiquitousContentNameKey: storeName} error:&error];
İşte sahip olduğunuz her tablodaki her kaydı silen bir sürüm.
Hızlı 4
static func resetDatabase() {
do {
try dataStore.persistentStoreCoordinator.managedObjectModel.entities.forEach { (entity) in
if let name = entity.name {
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: name)
let request = NSBatchDeleteRequest(fetchRequest: fetch)
try mainContext.execute(request)
}
}
try mainContext.save()
} catch {
print("error resenting the database: \(error.localizedDescription)")
}
}
Swift 4/5, iOS 9+
Tüm CoreData
SQLite dosyasını yeniden oluşturmak, tüm verilerin silinmesini sağlar, bu nedenle tüm varlıklar silinir. Sadece ara deleteAndRebuild()
.
class CoreDataStack {
// Change this
static let datamodelName = "ProjectName"
static let storeType = "sqlite"
static let persistentContainer = NSPersistentContainer(name: datamodelName)
private static let url: URL = {
let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent("\(datamodelName).\(storeType)")
assert(FileManager.default.fileExists(atPath: url.path))
return url
}()
static func loadStores() {
persistentContainer.loadPersistentStores(completionHandler: { (nsPersistentStoreDescription, error) in
if let error = error {
fatalError(error.localizedDescription)
}
})
}
static func deleteAndRebuild() {
try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: url, ofType: storeType, options: nil)
loadStores()
}
}
Tüm sürümlerle çalışır. Varlık adını iletin ve tüm girişleri silmek ve içeriği kaydetmek için tekrarlayın.
func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
var context = NSManagedObjectContext()
if #available(iOS 10.0, *) {
context = self.persistentContainer.viewContext
} else {
context = self.managedObjectContext
}
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
fetchRequest.entity = NSEntityDescription.entity(forEntityName: entityToFetch, in: context)
fetchRequest.includesPropertyValues = false
do {
let results = try context.fetch(fetchRequest) as! [NSManagedObject]
for result in results {
context.delete(result)
}
try context.save()
completion(true)
} catch {
completion(false)
print("fetch error -\(error.localizedDescription)")
}
}
Sıklıkla kullandığım (uygulama gereksinimine göre) diğer bir yöntem (silme toplu isteği dışında) kalıcı depoyu sıfırlamaktır. Uygulama iOS 10+ ve Swift için aşağıdaki gibi görünüyor (bir CoreDataManager sınıfınız olduğunu varsayarak):
let persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "<Data-Model-Name>“)
container.loadPersistentStores(completionHandler: { (storeDescription, err) in
if let err = err {
fatalError("loading of store failed: \(err)")
}
})
return container
}()
func resetPersistentStore() {
if let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.last {
let storeURL = persistentContainer.persistentStoreCoordinator.url(for: persistentStore)
do {
try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, ofType: NSSQLiteStoreType, options: nil)
} catch {
print("failed to destroy persistent store:", error.localizedDescription)
}
do {
try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
} catch {
print("failed to re-add persistent store:", error.localizedDescription)
}
}
}
Bu yöntemin bir avantajı, özellikle temel verilerinizdeki çok sayıda varlık için çok fazla veri kaydınız olduğunda daha basit olmasıdır. Bu durumda, bir toplu iş silme isteği bellek yoğun olur.
Swift 5.1 Çözümü
public static func reset() {
let coordinator = _persistentContainer.persistentStoreCoordinator
for store in coordinator.persistentStores where store.url != nil {
try? coordinator.remove(store)
try? FileManager.default.removeItem(atPath: store.url!.path)
}
}
Sqlite dosyasını ururpath dosyasından silin ve sonra derleyin.
MagicalRecord
Varsayılan bir kalıcılık deposu kullandığınızı ve varsayalım:
Belirli dosyaların var olduğunu ve / veya varlıkların adlarını veya sınıflarını girmeyi talep eden tüm çözümleri sevmiyorum. Bu, tüm varlıklardan tüm verileri silmenin hızlı ve güvenli bir yoludur. Sildikten sonra da taze bir yığın oluşturacak (aslında bu bölümün ne kadar gerekli olduğundan emin değilim).
Her şeyi silmek istediğinizde, ancak yeni bir veri almak için çalışan bir mağazaya ve moc'a sahip olduğunuzda (kullanıcı oturum açtığında ...) "çıkış" tarzı durumlar için godo.
extension NSManagedObject {
class func dropAllData() {
MagicalRecord.saveWithBlock({ context in
for name in NSManagedObjectModel.MR_defaultManagedObjectModel().entitiesByName.keys {
do { try self.deleteAll(name, context: context) }
catch { print("⚠️ ✏️ Error when deleting \(name): \(error)") }
}
}) { done, err in
MagicalRecord.cleanUp()
MagicalRecord.setupCoreDataStackWithStoreNamed("myStoreName")
}
}
private class func deleteAll(name: String, context ctx: NSManagedObjectContext) throws {
let all = NSFetchRequest(entityName: name)
all.includesPropertyValues = false
let allObjs = try ctx.executeFetchRequest(all)
for obj in allObjs {
obj.MR_deleteEntityInContext(ctx)
}
}
}
Bunu kullan
+(NSArray *)fetchDataFromEntity:(NSString *)entityName context:(NSManagedObjectContext *)context
{
NSFetchRequest * fetchRequest =[[NSFetchRequest alloc] init];
NSEntityDescription * CategoriesEntity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[fetchRequest setEntity:CategoriesEntity];
NSError * error;
NSInteger count = [context countForFetchRequest:fetchRequest error:&error];
if (count && count>0) {
NSArray * fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects && fetchedObjects.count>0) {
return fetchedObjects;
}else
return nil;
}
else
return nil;
}
+ (void)deleteObjectsOfArray:(NSMutableArray*)ary context:(NSManagedObjectContext *)context {
for (NSManagedObject * obj in ary) {
[context deleteObject:obj];
}
NSError *saveError = nil;
[context save:&saveError];
}
+ (void)deleteEntity:(NSString *)entityName context:(NSManagedObjectContext *)context {
NSArray *listArray = [self fetchDataFromEntity:entityName context:context];
[self deleteObjectsOfArray:[NSMutableArray arrayWithArray:listArray] context:context];
}
Grouchal'ın kodunu aldım ve hızlandırmak için eşzamanlı modla numaralandırma kullandım ( NSEnumerationConcurrent
), döngü için karşılaştırıldığında biraz daha hızlı oldu (uygulamamda Test için bu özelliği ekledim, böylece verileri silebilir ve silebilirler. uygulamayı yükle)
- (void)resetObjects
{
[self deleteAllObjectsInEntity:@"Entity1"];
[self deleteAllObjectsInEntity:@"Entity2"];
[self deleteAllObjectsInEntity:@"Entity3"];
[self deleteAllObjectsInEntity:@"Entity4"];
}
-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
MainDataContext *coreDataContext = [MainDataContext sharedInstance];
NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];
[items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
[currentContext deleteObject:obj];
}];
if (![currentContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@",entityName,error);
}
}
Burada tüm kayıtları silmek için swift3 sürümüm. 'Kullanıcılar' varlık adıdır
@IBAction func btnDelAll_touchupinside(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let fetchReq = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
let req = NSBatchDeleteRequest(fetchRequest: fetchReq)
do {
try managedObjectContext.execute(req)
} catch {
// Error Handling
}
}
NSBatchDeleteRequest
. stackoverflow.com/a/31961330/3681880