Question

Here is the problem.

  1. I have a method called -(void)searchingInBackground which is running in background (performSelectorInBackground).

  2. In this method, I have couple of different threads which are running in background too (performSelectorInBackground). Like this:

    -(void)searchingInBackground
    {
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getDuplicatedPictures:) withObject:copyArray];
      }
    
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getLocationsOfPhotos:) withObject:copyArray];
      }
    ... (and so on)
    }
    
  3. In each of functions in threads (ie. getDuplicatedPictures, getLocationsOfPhotos...) they will generate NSStrings at the end and I will use those strings to update my text field GUI.

  4. In order to update my text field GUI. I created a function called UpdateGUI which will use to help me update all of my NSStrings. Like this,

    -(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. Here is the problem, when I call this UpdateGUI using performSelectorOnMainThread in each of threads function. It will give me EXC_BAD_ACCESS. Here is what I did. For example:

    -(void)getDupicatedPictures
    {
         resultDupPhotos = .....;
         [self performSelectorOnMainThread:@selector(UpdateUI) withObject:nil waitUntilDone:YES];
    }
    
  6. If I do not use performSelectorOnMainThread, just set the values directly in those functions it works fine. I just want to better organize the code.

    -(void)getDuplicatedPictures
    {
         resultDupPhotos = .....;
         [_NumDupPhotosLabel  setStringValue: resultDupPhotos]; (works good and it will set the value to the GUI label)
    }
    

Could you guys tell me how to fix this? Thanks!!!

Was it helpful?

Solution

  • ARC or no?

  • if you have a crash, post the backtrace

  • surrounding a performInBackground:... call with an @autoreleasepool does nothing (NSAutoreleasePool isn't going to help, either -- you need the autorelease pool to be in the thread of execution)

  • if a variable is involved in a crash, show the variable's declaration and initialization

  • spawning a bunch of threads simultaneously to do a bunch of work is likely to be slower than doing the work sequentially. Concurrency should always be controlled. If you have a long running task, you might likely want to spin up a second thread. Or you might want to re-order operations. The issue, though, is that running multiple threads at once, especially if those threads are doing a lot of I/O, is just going to increase contention and may likely make things slower, often a lot slower.

More likely than not, one of the objects calculated on a background thread is being released before the main thread tries to use it. How do you ensure that resultDupPhotos is valid between threads?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top