2011-06-27 14 views
4

私はいくつかの情報を表示する必要があるUIViewを持っています。このビューは非常に複雑で、描画にはかなりの時間がかかるため、これをバックグラウンドスレッドに移動してメインスレッドをブロックしないようにしました。描画が終了すると、メインスレッドに戻ってImageViewを設定します。バックグラウンドスレッドのコンテキストへの描画

次のコードは私のための図面ですが、私は時々クラッシュを受けます。通常、Xcodeの[view release];でポイントと

NSManagedObjectID *objectID = [self.managedObject objectID]; 
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); 
     dispatch_async(queue,^{ 
      NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init]; 
      [backgroundContext setPersistentStoreCoordinator:[[self.managedObject managedObjectContext] persistentStoreCoordinator]]; 
      NSManagedObject *mo = [backgroundContext objectWithID:objectID]; 
      CGImageRef resultImage; 
      CGContextRef context; 
      void *bitmapData; 

    CGRect frame = self.frame; 
    frame.origin = CGPointZero; 

    CGColorSpaceRef colorSpace; 
    CGSize canvasSize; 
    int bitmapByteCount; 
    int bitmapBytesPerRow; 

    canvasSize = frame.size; 
    CGFloat scale = [UIScreen instancesRespondToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f; 
    canvasSize.width *= scale; 
    canvasSize.height *= scale; 

    bitmapBytesPerRow = (canvasSize.width * 4); 
    bitmapByteCount = (bitmapBytesPerRow * canvasSize.height); 

    //Create the color space 
    colorSpace = CGColorSpaceCreateDeviceRGB(); 

    bitmapData = malloc(bitmapByteCount); 

    //Check the the buffer is alloc'd 
    if(bitmapData == NULL){ 
     DLog(@"Buffer could not be alloc'd"); 
    } 

    //Create the context 
    context = CGBitmapContextCreate(bitmapData, canvasSize.width, canvasSize.height, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); 
    CGContextClearRect(context, CGRectMake(0, 0, canvasSize.width, canvasSize.height)); 

    // Setup transformation 
    CGContextSetInterpolationQuality(context, kCGInterpolationNone); 
    CGContextTranslateCTM(context, 0.0f, canvasSize.height); 
    CGContextScaleCTM(context, scale, -scale); 

    UIView *view = [[UIView alloc] initWithFrame:frame]; 
    [view setBackgroundColor:[UIColor clearColor]]; 

    UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(137, 5, 255, 30)]; 
    [nameLabel setFont:[UIFont fontWithName:@"Arial" size:22.0f]]; 
    [nameLabel setText:[mo valueForKey:@"name"]]; 
    [nameLabel setTextAlignment:UITextAlignmentRight]; 
    [view addSubview:nameLabel]; 
    [nameLabel release]; 
    nameLabel = nil; 
    ... Creating 20 or so label/imageviews all use 'mo' for data access to the NSManagedObject. 

    [view.layer renderInContext:context]; 
    [view release]; 
    view = nil; 
    //Get the result image 
    resultImage = CGBitmapContextCreateImage(context); 
    UIImage *viewImage = [UIImage imageWithCGImage:resultImage scale:0.0 orientation:UIImageOrientationUp]; 
    dispatch_async(dispatch_get_main_queue(),^ { 
     [dataImageView setImage:viewImage]; 
    }); 

    //Cleanup 
    free(bitmapData); 
    CGColorSpaceRelease(colorSpace); 
    CGImageRelease(resultImage); 
    CGContextRelease(context); 
}); 

Thread 6: Program received signal: EXC_BAD_ACCESSが、私はこのの頭や尾を作るカントので、あなたたちは、私を助けることを願って言います。あなたはUILabel(複数可)を作成するとき は、あなたがUIViewのに追加:私はいくつかの時間は、問題のこの可能性源を調査する-[UILabel hash]: message sent to deallocated instance 0x22841c00

答えて

0

てみコンソールに次のようなエラーが生じたNSZombieEnabled YESでそれを実行しようとしていますあなたはそれらを解放します(それは問題ありません)が、あなたはまたそれらを "拒否"します。ですから、この時点でUIViewに保持されているUILabelを持っていますが、同時にそれはnilを指しています! 最後に "view"をリリースすると、サブビューを解放しようとしますが、count = 1のUILabelに遭遇したがnilされた時点で、 "割り当て解除されたインスタンス"の例外が発生します。 これは、デバッガが[view release]で停止する理由と、NSZombieEnabledがUILabelの割り当てを解除しようとすると、なぜポインタがnilを指しているときに割り付け解除されたとみなすのかを示しています。 可能な解決策: "nameLabel = nil"ステートメントを削除します。

+1

答えに感謝しますが、最初はnameLabel = nilなしで試しました。 ( – mbogh

+0

)メモリ領域を指し示しておらず、メモリ領域へのポインタだけです。ビューは、メモリ領域へのすべての参照が解放されるまで、メモリに固定されます。 –

関連する問題