2012-10-17 28 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

唉,该死的,我确定这很明显!当然,最糟糕的事情发生了,我的对象被释放,所以互斥量是无用的。感谢捕捉;) –