6

lede'yi gömmemek için temel sorumu açacağım: neden NSFetchedResultsController'ın fetchedObjects diziliminin genellikle homojen olduğu, ancak nadir durumlarda İçerdiği yönetilen nesneler arasında __NSCFString?neden NSFetchedResultsController'ın fetchedObjects dizisi her zaman homojen değil

Ben uzun, uzun zamandır üretimde olan bir uygulama var. Birincil görünüm, temel veri yönetilen nesnelerin desteklediği bir video listesi içeren bir tablo görünümüdür. Tablo görünümü denetleyicisi ile yapılandırılmış bir NSFetchedResultsController kullanan bir NSFetchRequest oldukça sıradan: bu videolar bulutun içine yüklenebilir, bu tabloda görünümü denetleyicisi tablo görünümü hücreleri videoları tekabül ilerleme çubukları güncelleştirmek için zaman zaman bildirim alır

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[ABCVideo entityName]]; 
NSString *sectionKeyPath = nil; 
request.fetchBatchSize = 20; 
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:ABCVideoAttributes.recordingDate ascending:NO]; 
      sectionKeyPath = @"sectionIdentifier"; 
request.sortDescriptors = @[sort]; 
request.predicate = [NSPredicate predicateWithFormat:@"owner = %@ and %K = %@", person, ABCVideoAttributes.serverDeleted, @(NO)]; 
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:sectionKeyPath cacheName:kABCMyVideosTableViewControllerCacheKey]; 

Şu anda yükleniyor. Bu geri bildirimin içinde, bildirime karşılık gelen videoyu bulmak için NSFetchedResultsController'un fetchedObjects dizisini alıyoruz, böylece doğru tablo görüntüleme hücresi ilerleme çubuğunu güncelleyebilir.

Tüm bu çalışmalar. Zamanın% 99,9'u, her seferinde </RonBurgundy> çalışır.

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x136f24480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key guid.'

:

Ama benim bildirim işleyicisi fetchedObjects bir filteredArrayUsingPredicate almaya çalışırken ne olur bir SIGABRT başlamıştı nadir, nadir bir vaka olduğuna bizim HockeyApp kilitlenme raporlarında fark

Geçtiğimiz günlerde bu çökmeyi zaman zaman yeniden üretebileceğim bir durum bulmayı başardım ve çok fazla deneyden sonra, fetchedObjects dizisinin bazen ABCVideo olmayan bir şey içerdiğini keşfettim: bunun yerine dizideki bir yuva tarafından işgal edildi. __NSCFString örneği. Bu, NSFetchRequestResultTypeNSManagedObjectResultType öğesinin verildiği ve bir dizenin yönetilen bir nesne olmadığı göz önüne alındığında oldukça şaşırtıcıydı.

Yani sol merak ediyorum: Bu bir çekirdek Veri hatadır? Veya dizimde önceden ayrılmış bir ABCVideo örneğine işaret eden bir işaretçi var ve öbek üzerindeki bu konum daha sonra bir __NSCFString örneğiyle alındı? Eğer ikincisiyse, bu nasıl olabilir? ARC kullanıyorum, bu nedenle bu videolardan birinin nasıl dağıtılabileceğini anlamak zor.

+0

Çekirdek Veri hatası olduğundan şüpheleniyorum. iOS9, özellikle NSFetchedResultsControllers ile çeşitli hatalar getirdi ve bu da başka bir şey olabilir. – Avi

+0

Dizinin kendisi, nesneleri birçoğunu '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ', aksi halde serbest bırakılmasınlar diye sürece saklamalıdır. Ayrıca, ARC ile, bu neredeyse kesinlikle böyle değil. Bir ARC hatası veya Çekirdek Veri hatası olabilir. Bunun, 'NSFetchedResultsController' ile önbelleğe almayla ilgili olduğunu biliyor musunuz? Önbelleğe almayı devre dışı bırak ve çoğalt? – SmokeDispenser

+0

Yeniden üretebileceğinizden, bunun ne zaman olduğunu algılamak ve dizenin içeriğini incelemek yararlı olabilir. Dizenin neden orada olduğunu bilmiyorum, ancak içeriği bir nedene işaret edebilir. –

cevap

4

NSFastEnumeration ile -[NSFetchedResultsController fetchedObjects] numaralı bellek yönetimi hatası var. Nesne 0x136f24480, ABCVideo idi ancak ayrıldı. Bu bellek, __NSCFString'i depolamak için kullanıldı. Mesajları yanlış nesnelere göndermek, EXC_BAD_ACCESS ve SIGABRT yaygın sonuçtur.

Bu hata benim uygulama olarak da ama ben bile bir kez yeniden. Sorunu yeniden oluşturabilecek bir örnek proje paylaşmaya istekliyseniz, çözmek için birlikte çalışabiliriz.

Birden çok geçici çözüm var. Anahtar birisi bu okuma Swift NSFastEnumeration kullanılarak NSArray için Array dönüştürür çünkü, hatta fetchedObjects arayarak çöküyor alacak Swift kullanıyorsa, maalesef Eğer fetchedObjects

// 1 
NSArray *fetchedObjects = controller.fetchedObjects 
for (int i = 0; i < fetchedObjects.count; ++i) { 
    NSManagedObject *object = fetchedObjects[i]; 
} 

// 2 
NSArray <id<NSFetchedResultsSectionInfo>> *sections = controller.sections; 
for (int s = 0; s < sections.count; ++s) { 
    id<NSFetchedResultsSectionInfo> section = sections[s]; 
    for (int i = 0; i < [section numberOfObjects]; ++i) { 
     NSManagedObject *object = [controller objectAtIndexPath:[NSIndexPath indexPathForItem:i inSection:s]]; 
    } 
} 

// 3 Fetch from NSManagedContextDirectly 

üzerinde NSFastEnumeration kaçınmaktır.

+0

Bu soruya gerçekten cevap vermiyor. Farklı bir sorunuz varsa, [Soru Sor] 'u tıklayarak sorabilirsiniz (http://stackoverflow.com/questions/ask). Ayrıca, bu soruya daha fazla dikkat çekmek için [bir ödül de ekleyebilirsiniz] (http://stackoverflow.com/help/privileges/set-bounties). - [Yorum yaz] (/ review/düşük kaliteli yazılar/11031964) – ChrisStillwell

+1

@ChrisStillwell Nereden geldiğinizi anladığımdan emin değilim. Sorunun yazarı olarak, bunun doğru olup olmadığını sorduğum soruya bir cevap olarak düşünürdüm. (Dizi neden homojen değildir? Çünkü serbest nesnelerdeki sahte işaretçiler tesadüfi olarak diğer türlerle olan şeylere işaret eder). – pohl

+0

Bu hata, iOS 8.x'den beri var. Apple’a bildiren birinin olup olmadığından emin değilim. En azından muhabirin Apple için örnek projeler olmadığını tahmin ediyorum. Apple, hiçbir örnek proje sağlanmadığında hata olmadığını iddia ediyor. – keithyip

İlgili konular