6

Vì vậy mà tôi không chôn dấu, tôi sẽ mở câu hỏi cốt lõi của mình: tại sao mảng fetchedObjects của NSFetchedResultsController thường là đồng nhất, nhưng trong những dịp hiếm hoi có chứa __NSCFString trong số các đối tượng được quản lý phải chứa?tại sao mảng fetchedObjects của NSFetchedResultsController không phải lúc nào cũng đồng nhất

Tôi có một ứng dụng đã được sản xuất trong một thời gian dài. Đó là chế độ xem chính là chế độ xem bảng chứa danh sách video, được hỗ trợ bởi các đối tượng được quản lý dữ liệu lõi. Bộ điều khiển xem bảng sử dụng một NSFetchedResultsController cấu hình với một khá bình thường NSFetchRequest:

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]; 

Kể từ khi những đoạn phim này có thể được tải vào trong đám mây, điều khiển xem bảng này được thông báo thường xuyên để cập nhật thanh tiến trình trong các tế bào xem bảng tương ứng với video hiện đang được tải lên. Bên trong cuộc gọi lại này, chúng tôi đang nhận mảng fetchedObjects của NSFetchedResultsController để tìm video tương ứng với thông báo, để ô xem bảng chính xác có thể cập nhật thanh tiến trình của nó.

Tất cả đều hoạt động. 99,9% thời gian, nó hoạt động mỗi lần </RonBurgundy>.

Nhưng tôi nhận thấy trong báo cáo sự cố HockeyApp của chúng tôi rằng có một hiếm, trường hợp hiếm hoi mà tôi đã nhận được một SIGABRT điều đó xảy ra khi xử lý thông báo tôi đang cố gắng để có được một filteredArrayUsingPredicate từ fetchedObjects:

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

Gần đây, tôi đã tìm được một trường hợp mà thỉnh thoảng tôi có thể tái tạo vụ tai nạn này, và sau rất nhiều thử nghiệm, tôi phát hiện ra rằng mảng fetchedObjects đôi khi chứa một thứ không phải là ABCVideo: thay vào đó, một vị trí trong mảng bị chiếm bởi một __NSCFString bản sao. Điều này khá đáng ngạc nhiên, với điều kiện NSFetchRequestResultTypeNSManagedObjectResultType và một chuỗi không phải là đối tượng được quản lý.

Vì vậy, tôi tự hỏi: đây có phải là lỗi về Dữ liệu cốt lõi không? Hoặc mảng của tôi có chứa một con trỏ trước đây đã trỏ đến một cá thể ABCVideo đã được deallocated và vị trí đó trên heap sau đó đã được thực hiện bởi một cá thể __NSCFString? Nếu đó là sau này, thì làm thế nào điều này có thể xảy ra? Tôi đang sử dụng ARC, do đó, thật khó để hiểu cách một trong các video này có thể bị phân phối lại.

+0

Tôi nghi ngờ lỗi Lõi dữ liệu. iOS9 đã giới thiệu một số lỗi, đặc biệt là với NSFetchedResultsControllers, và điều này có thể khác. – Avi

+0

Bản thân mảng nên giữ lại các đối tượng của nó, trừ khi bạn bằng cách nào đó 'giải phóng' một quá nhiều, chúng không nên được giải phóng. Ngoài ra, với ARC, điều này gần như chắc chắn không phải là trường hợp. Có thể là lỗi ARC hoặc lỗi Lõi dữ liệu. Bạn có thể loại trừ điều này liên quan đến bộ nhớ đệm với 'NSFetchedResultsController' không? Vô hiệu hóa bộ nhớ đệm và tái tạo? – SmokeDispenser

+0

Vì bạn có thể tái tạo nó, nó có thể hữu ích để phát hiện khi điều này xảy ra và kiểm tra nội dung của chuỗi. Tôi không biết tại sao chuỗi lại ở đó, nhưng nội dung của nó có thể hướng tới một nguyên nhân. –

Trả lời

4

Có lỗi quản lý bộ nhớ trong -[NSFetchedResultsController fetchedObjects] với NSFastEnumeration. Đối tượng 0x136f24480 là ABCVideo nhưng bị deallocated. Đó là bộ nhớ đã được sử dụng để lưu trữ __NSCFString. Gửi tin nhắn đến các đối tượng sai, EXC_BAD_ACCESS và SIGABRT là kết quả chung.

Lỗi này cũng có trong ứng dụng của tôi nhưng tôi không thể tạo lại nó ngay cả một lần. Nếu bạn sẵn sàng chia sẻ một dự án mẫu có thể tái tạo vấn đề, chúng ta có thể làm việc cùng nhau để giải quyết nó.

Có nhiều giải pháp thay thế. Điều quan trọng là để tránh NSFastEnumeration trên 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 

Nếu không may, có người đọc bài viết này đang sử dụng Swift, bạn sẽ nhận được tai nạn thậm chí gọi fetchedObjects vì Swift chuyển đổi NSArray-Array sử dụng NSFastEnumeration.

+0

Điều này không thực sự trả lời câu hỏi. Nếu bạn có một câu hỏi khác, bạn có thể hỏi nó bằng cách nhấp vào [Hỏi câu hỏi] (http://stackoverflow.com/questions/ask). Bạn cũng có thể [thêm tiền thưởng] (http://stackoverflow.com/help/privileges/set-bounties) để thu hút thêm sự chú ý cho câu hỏi này. - [Từ đánh giá] (/ review/low-quality-posts/11031964) – ChrisStillwell

+1

@ChrisStillwell Tôi không chắc tôi hiểu bạn đến từ đâu. Là tác giả của câu hỏi, tôi sẽ xem đây là câu trả lời cho câu hỏi của tôi nếu nó là sự thật. (Tại sao mảng không đồng nhất? Bởi vì các con trỏ giả mạo để phát hành các đối tượng trùng hợp ngẫu nhiên với mọi thứ với các kiểu khác). – pohl

+0

Lỗi này đã tồn tại kể từ iOS 8.x. Tôi không chắc liệu có ai báo cáo với Apple không. Tôi đoán rằng ít nhất phóng viên không có bất kỳ dự án mẫu nào cho Apple. Apple thích giả vờ rằng không có lỗi nếu không có dự án mẫu nào được cung cấp. – keithyip

Các vấn đề liên quan