나는 무엇이 계속 진행되고 있는지 이해할 수 없을 때 매우 이상한 문제가 있으므로 설명을 찾고 있습니다. 상황은 다음과 같습니다 :CoreData 데이터가 백그라운드 스레드에로드 될 때
나는 세 개의 하위 뷰가있는 scrollview가있는보기 컨트롤러가 있습니다. 이 세 파단이 백그라운드 스레드에서 CoreData를 사용하여 데이터베이스의 내용을로드하는 방법
-(void)loadContent
가로드 된 항목을 나타내는 및 호출 자신의 파단으로 추가 파단 생성이 [자기 addSubview를 : itemView] 그 방법은 내가 싱글 서비스 클래스를 사용하고 DB에서 데이터를로드하려면
[self performSelectorInBackground: @selector(loadContent) withObject: nil];
로 호출됩니다. 모든 것이 잘 작동했지만 세 가지보기에서 데이터의 일부가로드되는 경우 앱이 충돌하는 경우가 있습니다.
나는이 모든 읽기 작업에 대해 하나 개의 NSManagedObjectContext 인스턴스를 공유하기 때문에 그것의 추측, 그래서 그것은 단지 NSManagedObjectModel 및 NSPersistentStoreCoordinator 인스턴스 공유하고 자신의 NSManagedObjectContext 인스턴스의 생성하도록 클래스를 다시 썼다.갑자기 매우 이상한 일이 일어났습니다. 데이터가로드됩니다. 하위 뷰가 생성되어 뷰 계층 구조에 추가되지만 화면에 표시되지 않습니다. 이전 싱글 톤 서비스 클래스 (하나의 managedObjectContext 공유)로 다시 전환하면 매력과 같이 다시 작동합니다! (하지만 앱을 충돌시킬 위험이 있음).
DB에서 데이터를로드하는 것이 화면에 항목을 표시하는 것과 관련이 있다는 사실을 절대 알지 못합니다. 그 이상 - 하위 뷰가 생성되어 뷰 계층에 추가 될 때 왜 그 뷰가 표시되지 않습니까?
소스는 다음과 같습니다
- (void) loadContent {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *results = [(WLDataService *)[WLDataService service] loadItemsForGDView];
NSUInteger channelPosition = 0;
CGFloat position = 0.0;
CGFloat minuteWidth = ((self.superview.frame.size.width/2.0)/60.0);
for(Item *it in results) {
/// On following lines size and position of the view is computed according to item setup - skipping here...
/// Create item; it's simple subclass of UIView class
WLGDItemView *item = [[WLGDItemView alloc] init];
/// Variables used here are declared above when size and position is computed
item.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
[self performSelectorOnMainThread: @selector(addSubview:) withObject: item waitUntilDone: NO];
/// This is just helper macro to release things
WL_RELEASE_SAFELY(item);
}
[pool drain];
}
다음과 같이 기본 서비스 클래스 (싱글 톤이 아닌 하나)의 구현이다 (다만 흥미로운 부분) : 정말 그러고 싶어
#import "WLLocalService.h"
static NSPersistentStoreCoordinator *sharedPSC = nil;
static NSManagedObjectModel *sharedMOM = nil;
@implementation WLLocalService
@synthesize managedObjectContext;
/// This is here for backward compatibility reasons
+ (WLLocalService *) service {
return [[[self alloc] init] autorelease];
}
#pragma mark -
#pragma mark Core Data stack
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
[managedObjectContext setUndoManager: nil];
[managedObjectContext setMergePolicy: NSMergeByPropertyStoreTrumpMergePolicy];
}
return managedObjectContext;
}
- (NSManagedObjectModel *) managedObjectModel {
if(sharedMOM == nil) {
sharedMOM = [[NSManagedObjectModel mergedModelFromBundles: nil] retain];
}
return sharedMOM;
}
- (NSPersistentStoreCoordinator *) persistentStoreCoordinator {
if(sharedPSC == nil) {
NSURL *storeUrl = [self dataStorePath];
NSError *error = nil;
sharedPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![sharedPSC addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: storeUrl options: nil error: &error]) {
WLLOG(@"%@: %@", error, [error userInfo]);
}
}
return sharedPSC;
}
#pragma mark -
#pragma mark Path to data store file
- (NSURL *) dataStorePath {
return [NSURL fileURLWithPath: [WL_DOCUMENTS_DIR() stringByAppendingPathComponent: @"/DB.sqlite"]];
}
- (void)dealloc {
WL_RELEASE_SAFELY(managedObjectModel);
[super dealloc];
}
@end
왜 여기에서 일어나고 있는지 그리고 왜 이상하게 행동하는지 (그리고 물론 - 왜 그것이 작동하지 않는지, 특히). 아무도 그것을 설명 할 수 있습니까? 모든
예, 나는 허밍 된 시간을 읽었습니다. 그래서 싱글 톤 클래스를 수정하려고했는데 싱글 톤이 아니며 각 인스턴스에 대해 별도의 관리되는 객체 컨텍스트를 사용했습니다. 스레드간에 관리 객체 인스턴스를 보내지 않고, 매개 변수에 따라 그래픽 표현을 작성하는 중입니다. 그리고 왜 UIView 개체가 표시되지 않습니다 혼란 스러워요! – Matthes
'완전 동시 작업의 경우 각 스레드마다 다른 코디네이터가 필요합니다.'라는 부분을 놓쳤습니다. 그때. 비 싱글턴은 PSC 및 MOM의 싱글 톤 인스턴스를 추적하는 전역 변수가 있으므로 싱글 톤처럼 작동합니다. 여러 스레드에서 해당 코드를 사용하고 있으므로 동시성 문제가 발생할 수 있습니다. 그 (것)들에 접근을 동기화하지 않기 때문에 초기화 할 때 확실히 잠재적 인 문제가있다. –
그래서 서비스 클래스를 수정하여 각 인스턴스가 자신의 코디네이터 인스턴스와 관리 객체 컨텍스트를 유지하고 두 접근 자 메서드가 동기화됩니다. 그러나 변경 사항은 없습니다. 뷰의 내용은 여전히 표시되지 않습니다. 나는 그것이 가능하고 어떻게 DB에서 데이터를 로딩하고 완전히 다른 것을 디스플레이하는지 사이의 관계가 무엇인지 알지 못한다. 아 !!! – Matthes