简体   繁体   中英

Objective c: Bad access error when using performSelectorOnMainThread

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!!!

  • 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM