2012-10-17 30 views
0

我有一個OpenGL應用程序需要在顯示數據前在後臺執行一些計算。Objective-C:同步塊和GCD

隨後,我在做什麼是:

  1. prepareData(電話後臺線程)
  2. _doLongComputation(在後臺線程調用_transferToGPU
  3. _transferToGPU(主線程)

因爲我在同一個對象glData上使用​​塊,所以關鍵部分不應該'不能同時被多個線程訪問,但不幸的是情況並非如此,我不知道爲什麼。

任何想法?

代碼的重要部分是以下:

@property (atomic, retain) NSData *glData; 

...snip snip... 

- (void) _doLongComputation { 
    @synchronized (glData) { 
    // Create a buffer (long operation, done in C++) 
    unsigned long size; 
    unsigned char* buffer = createBuffer(&size); 

    // Create NSData to hold it safely 
    self.glData = [NSData dataWithBytesNoCopy:buffer length:size freeWhenDone:YES]; 
    } 

    // Don't wand to deal with locking the OpenGL context, 
    // so we do all the OpenGL-related stuff in the main queue 
    dispatch_async (dispatch_get_main_queue(), ^{ 
    [self _transferToGPU]; 
    }); 
} 

- (void) _transferToGPU { 
    @synchronized (glData) { 
    ...snip snip... 

    // Transfer buffer to GPU 
    glBufferData(GL_ARRAY_BUFFER, 
       glData.length, 
       glData.bytes, 
       GL_STATIC_DRAW); 

    // We're done, so set the buffer to nil 
    self.glData = nil; 
    } 
} 

- (void) prepareData { 
    [self performSelectorInBackground:@selector(_doLongComputation)]; 
} 

回答

2

我想你應該不是自我同步。

在變量上同步從概念上使用該變量指向的地址創建隱式互斥。如果變量指向不同的對象,它將是一個不同的互斥體,即使它仍然是代碼中的相同變量。這意味着在您的@synchronized(glData)塊中設置glData會失敗同步嘗試的目的。

+0

唉,該死的,我確定這很明顯!當然,最糟糕的事情發生了,我的對象被釋放,所以互斥量是無用的。感謝捕捉;) –