Objective-C:同步块和GCD

时间:2012-10-17 23:24:31

标签: objective-c opengl grand-central-dispatch synchronized

我有一个OpenGL应用,需要在显示数据之前在后台执行一些计算。

顺便说一下,我正在做的是:

  1. prepareData(调用后台线程)
  2. _doLongComputation(在后台主题中,调用_transferToGPU
  3. _transferToGPU(主线索)
  4. 由于我在同一个对象synchronized上使用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)];
    }
    

1 个答案:

答案 0 :(得分:2)

我认为你应该自我同步。

在变量上同步在概念上使用该变量指向的地址创建隐式互斥锁。如果变量指向不同的对象,它将是一个不同的互斥锁,即使它仍然是代码中的相同变量。这意味着在@synchronized(glData)块中设置glData会破坏同步尝试的目的。