目标c:使用performSelectorOnMainThread时访问错误

时间:2013-05-22 15:15:48

标签: objective-c macos cocoa performselector

这是问题所在。

  1. 我有一个名为 - (void)searchInBackground的方法,它在后台运行(performSelectorInBackground)。

  2. 在这个方法中,我有几个不同的线程也在后台运行(performSelectorInBackground)。像这样:

    -(void)searchingInBackground
    {
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getDuplicatedPictures:) withObject:copyArray];
      }
    
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getLocationsOfPhotos:) withObject:copyArray];
      }
    ... (and so on)
    }
    
  3. 在线程中的每个函数(即getDuplicatedPictures,getLocationsOfPhotos ...)中,它们将在最后生成NSStrings,我将使用这些字符串来更新我的文本字段GUI。

  4. 为了更新我的文本字段GUI。我创建了一个名为UpdateGUI的函数,它将用于帮助我更新所有NSStrings。像这样,

    -(void)UpdateUI
    {
       [_NumDupPhotosLabel(label for GUI)  setStringValue: resultDupPhotos(string from thread function which is getDuplicatedPictures in this case)];
        ....(includes all of my strings from threads)
    }
    
  5. 这是我在每个线程函数中使用performSelectorOnMainThread调用此UpdateGUI的问题。它会给我EXC_BAD_ACCESS。这就是我做的。 例如:

    -(void)getDupicatedPictures
    {
         resultDupPhotos = .....;
         [self performSelectorOnMainThread:@selector(UpdateUI) withObject:nil waitUntilDone:YES];
    }
    
  6. 如果我不使用performSelectorOnMainThread,只需在这些函数中直接设置它就可以正常工作。我只想更好地组织代码。

    -(void)getDuplicatedPictures
    {
         resultDupPhotos = .....;
         [_NumDupPhotosLabel  setStringValue: resultDupPhotos]; (works good and it will set the value to the GUI label)
    }
    
  7. 你能告诉我如何解决这个问题吗?感谢!!!

1 个答案:

答案 0 :(得分:1)

  • ARC还是没有?

  • 如果您遇到崩溃,请发布回溯

  • 使用performInBackground:...围绕@autoreleasepool调用不会做任何事情(NSAutoreleasePool也无济于事 - 您需要自动释放池 in执行的线程

  • 如果变量涉及崩溃,则显示变量的声明和初始化

  • 同时产生一堆线程做一堆工作可能比顺序工作要慢。应始终控制并发。如果您有一个长时间运行的任务,可能可能想要启动第二个线程。或者您可能想要重新排序操作。但问题是,一次运行多个线程,特别是如果这些线程执行大量I / O,只会增加争用,并且可能会使速度变慢,通常会慢得多。

更有可能的是,在主线程尝试使用它之前,正在释放在后台线程上计算的一个对象。您如何确保resultDupPhotos在线程之间有效?