2011-06-27 53 views
4

我有一個UIView必須顯示一些信息。由於這個視圖非常複雜,並且繪圖需要大量的時間,所以我將它移到後臺線程以避免阻塞主線程。繪圖完成後,我將發回主線程以設置ImageView。繪製到背景線程上下文

以下代碼爲我繪製圖形,但我收到一些偶爾的崩潰。在[view release];通常的Xcode點,並說Thread 6: Program received signal: EXC_BAD_ACCESS

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); 
}); 

希望你們能幫助我,因爲我不能讓這頭或尾。我曾嘗試與NSZombieEnabled是一些次導致以下錯誤控制檯-[UILabel hash]: message sent to deallocated instance 0x22841c00

回答

0

嘗試以調查問題的這種可能的來源運行它: 當您創建的UILabel(S)將它們添加到了UIView然後你釋放它們(沒關係),但你也「無」他們。所以在這一點上,你有UIView保留的UIVabel,但在同一時間,它指向零! 因此,最終當你釋放「視圖」時,它會嘗試釋放它的子視圖,並且一旦遇到保留count = 1但已被刪除的UILabel,它就會得到「解除分配的實例」異常。 這可以證明爲什麼調試器在[視圖發佈]停止,爲什麼NSZombieEnabled抱怨嘗試釋放UILabel:它將其視爲釋放,因爲指針指向nil。 所以可能的解決方案:刪除「nameLabel = nil」語句。

+1

感謝您的答案,但一開始我嘗試沒有nameLabel =零;聲明和結果是一樣的,偶爾發生崩潰:( – mbogh

+0

)您不會刪除內存區域,只有指向內存區域的指針。該視圖將一直存儲在內存中,直到所有引用都被釋放爲止。 –