3

AVCaptureSessionを使用して、AVCaptureVideoDataOutputクラスのsetSampleBufferDelegateメソッドを使用してカメラからフレームをキャプチャしています。デリゲートメソッドは次のようになります。私はUIImageに変換し、UIImageViewに配置することがわかります。各UIImageをディスクに保存してURLを新しいmanagedObjectに格納したいのですが、各呼び出しがシリアルディスパッチキューを使用して新しいスレッドを生成するので、managedObjectContextを正しく取得する方法がわかりません。誰でも、CoreDataとディスパッチキューを使用するソリューションを提案することができます。これは、ディスクに保存され、managedObjectに対応するイメージのコレクションを構築する方法です。AVCaptureSession出力サンプルバッファをCoreDataに保存

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
/*Lock the image buffer*/ 
CVPixelBufferLockBaseAddress(imageBuffer,0); 
/*Get information about the image*/ 
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
size_t width = CVPixelBufferGetWidth(imageBuffer); 
size_t height = CVPixelBufferGetHeight(imageBuffer); 

/*Create a CGImageRef from the CVImageBufferRef*/ 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

    /*We release some components*/ 
    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace); 

/*We display the result on the image view (We need to change the orientation of the image so that the video is displayed correctly). 
    Same thing as for the CALayer we are not in the main thread so ...*/ 
    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight]; 

/*We relase the CGImageRef*/ 
CGImageRelease(newImage); 

[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES]; 

/*We unlock the image buffer*/ 
CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

[pool drain]; 
} 

答えて

2

recommended solutionは、スレッドごとに単一NSPersistentStoreCoordinatorに各ポインティングを新しいNSManagedObjectContextを作成することです。 NSManagedObjectContextDidSaveNotificationを聞いて、変更をメインスレッドのコンテキストにマージすることもできます(適切な名前はmergeChangesFromContextDidSaveNotification:です)。

は個人的に、私は、スレッドごとのコンテキストを処理するための中心的な場所でこのようなアクセサを使用したい:あなたはコンテキストを渡すことができますよりも、任意の容易なスレッド間NSManagedObjectsを渡すことはできませんことを

- (NSManagedObjectContext *) managedObjectContext { 
    NSManagedObjectContext *context = [[[NSThread currentThread] threadDictionary] objectForKey:@"NSManagedObjectContext"]; 
    if (context == nil) { 
     context = [[[NSManagedObjectContext alloc] init] autorelease]; 
     [context setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 
     [[[NSThread currentThread] threadDictionary] setObject:context forKey:@"NSManagedObjectContext"]; 
    } 
    return context; 
} 

覚えていますか。その代わりに、NSManagedObjectID(オブジェクトのobjectIDプロパティから)を渡す必要があります。次に、宛先スレッドで、そのスレッドのコンテキストのobjectWithID:メソッドを使用して、同等のオブジェクトを取得します。

関連する問題