güncellemesinden sonra getirilen değerleri yeni ekler/kaldırmaz. Benzer sorulardan sonra, şu ifadeyle başlamak istiyorum: "NSFetchedResultsController delegesini ayarlamıştım, işe yaramadı." .NSFetchedResultsController,
Bu yüzden hücreleri NSFetchedResultsController ile doldurulmuş basit bir TableViewController var. Ayrıca NSFetchedResultsController temsilci yöntemleri bazı ayıklama etiketlerle uygulayan
@property (strong, nonatomic) NSFetchedResultsController *frc;
...
- (NSFetchedResultsController *)frc
{
if (!_frc)
{
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:e_product];
request.sortDescriptors = [NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:@"product_group.product_group_name" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:f_product_name ascending:YES],
nil];
_frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[DTGGlobalSettings sharedInstance].moc sectionNameKeyPath:@"product_group.product_group_name" cacheName:nil];
_frc.delegate = self;
[_frc performFetch:&error];
if (error)
{
NSLog(@"Error while fetching products: %@!", error.userInfo);
}
}
return _frc;
}
: Burada FRC init kod ben yenile düğmesine sahip benim NavigationBar yılında
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
NSLog(@"controllerWillChangeContent");
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
NSLog(@"didChangeObject - insert");
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"didChangeObject - delete");
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
NSLog(@"didChangeObject - update");
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
NSLog(@"didChangeObject - move");
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
NSLog(@"didChangeSection - insert");
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"didChangeSection - delete");
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
NSLog(@"controllerDidChangeContent");
[self.tableView endUpdates];
}
, işlevi ürün kataloğunu ateşlemek için Aşağıdakileri yapan yöntem: 1. Uzak MySQL sunucusundan ürünler getiriliyor 2. Kimliği olan ürün mevcut değilse - oluşturur ve tüm alanları doldurur 3. Varsa, tüm alanlar, tüm alanlara göre güncelleştirilir. getirilen değerler
2. ve 3. sıradan sonra mağaza kaydedilir. Uygulamadaki tüm CoreData işlemlerinde tek bir NSManagedObjectContext kullanıyorum.
Uygulamayı ilk kez başlattığımda, henüz getirilmeyen ürün olmadığından TVC boş. Yenile'ye bastığımda, yeni ürünler ManagedObjectContext'e getirilir ve eklenir, ancak NSManagedObjectContext herhangi bir değişiklik görmez/duymaz: delege yöntemleri çağrılmaz, bu nedenle TVC'ye yeni satır eklenmez. Uygulamayı yeniden başlattığımda, yeni ürünler TVC'ye hiçbir sorun olmadan getiriliyor.
Orada bazı ürünler olduğunda yenileme düğmesine bir kez daha basarsam, kısa bir süre sonra hepsi kaybolur. Bazı hata ayıklama, varlıkların alanlarını güncelleştirdikten sonra gerçekleşirse (aslında değerler aynıdır) ve mağazayı kaydederken bana gösterdi. Temsilci yöntemleri bu kez bir çekicilik ve her güncelleştirilmiş ve kaydedilen varlık denetleyicisi için çalışır: didChangeObject: atIndexPath: forChangeType: newIndexPath forChangeType = NSFetchedResultsChangeDelete ile çağrılır.
Soru # 1: Neden NSFetchedResultsController uygulama yeniden başlatılmadan eklenen varlıkları göremiyor? Soru # 2: Neden NSFetchedResultsController işaretleri zaten var olmayan "var olmayan" (?) Işaretler ve mağaza kaydettikten sonra bunları TVC'den kaldırır?
ben olmanın bütün Geçen hafta bu konuyla mücadele herhangi bir yardım ve fikir takdir ediyorum; (() Jody için
UPD1: İşte bazı ayrıntılar bazı değişkenler paylaşmak için özel sınıf DTGGlobalSettings kullanmak vardır. . nedense onay kutusu "Kullanım CoreData" yeni oluşturarak görmüyorum çünkü
+(DTGGlobalSettings *)sharedInstance
{
static DTGGlobalSettings *myInstance = nil;
if (nil == myInstance)
{
myInstance = [[[self class] alloc] init];
// set values here
// try to acces MOC to init CoreData
[myInstance moc];
myInstance.baseURL = @"http://local.app/";
}
return myInstance;
}
, Apple belgelerine bir örnek kullanılan CoreData yığınını init için: app genelinde Ben onun sharedInstance özelliğini init nasıl Xc'de daha önce gördüğümden eminim gazel, ama şimdi yok; ((Xcode 4.4.1): Ben CoreData erişmesi gereken yere
#pragma mark Core Data stack
- (NSManagedObjectContext *) moc {
if (_moc != nil) {
return _moc;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_moc = [[NSManagedObjectContext alloc] init];
[_moc setPersistentStoreCoordinator: coordinator];
}
return _moc;
}
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeUrl = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
storeUrl = [storeUrl URLByAppendingPathComponent:DOC_NAME];
NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
NSLog(@"Error adding a store to the coordinator: %@, %@", error, error.userInfo);
}
return _persistentStoreCoordinator;
}
-(void)saveDataStore
{
NSError *error;
if (![self.moc save:&error]) NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
DTGGlobalSettings ait 'moc' (ManagedObjectContext) özelliği ardından uygulamanın her yerde kullanılır.
Şimdi ikinci bölüme, veritabanını güncelleştirin.JSON biçiminde uzak web sunucusundan bazı yeni varlıklar alıyorum, sonuçta ortaya çıkan sözlüğü gidiyorum ve istek sonuçlarında bulunan her varlık için createFromDictionary yöntemini çağırıyorum. İşte kod: Ben fethed varlıkların bittiğinde
+(Product *)createFromDictionary:(NSDictionary *)entityData inContext:(NSManagedObjectContext *)moc performUpdate:(BOOL)update
{
Product *result;
if (update)
{
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:e_product];
request.predicate = [NSPredicate predicateWithFormat:@"%K = %@", f_product_id, [entityData objectForKey:f_product_id]];
result = [[DTGGlobalSettings sharedInstance].moc executeFetchRequest:request error:nil].lastObject;
if (!result)
{
NSLog(@"Error updating Product ID %@! Cannot fetch entity.", [entityData objectForKey:f_product_id]);
return nil;
}
} else
{
result = [NSEntityDescription insertNewObjectForEntityForName:e_product inManagedObjectContext:[DTGGlobalSettings sharedInstance].moc];
}
result.product_id = [[DTGGlobalSettings sharedInstance].numFormatter numberFromString:[entityData objectForKey:f_product_id]];
result.product_image = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[DTGGlobalSettings sharedInstance].baseURL stringByAppendingString:[entityData objectForKey:f_product_image]]]];
result.product_name = [entityData objectForKey:f_product_name];
return result;
}
, ben [[DTGGlobalSettings sharedInstance] saveDataStore] (yukarıya bakınız) diyoruz. Bu noktada, TVC'deki mevcut satırlar (eğer varsa) ortadan kayboldu. Bazı yeni varlıklar ekliyor olsaydım, hiçbir şey olmayınca, yani TVC satırlarını güncellemez.
Yanlış kod gönderdiniz. İlginç bitler, verileri veritabanınıza nasıl aktaracağınız ve hem içe aktarma hem de getirilen sonuç denetleyicisi için temel veri kümesini nasıl ayarlayacağınızdır. –
UPD1'de sorduğunuz bazı ayrıntıları ekledim. Umarım artık bununla ilgili olarak ... – Arseniy
güncellemeyle ilgili ne düşündüğüm daha net? – Arseniy