[IOS] (transfer) EXC_BAD_ACCESS(code=2,address=0xcc exception solution and it is recommended not to refresh the interface in the child thread

Reprinted from: http://www.cnblogs.com/ygm900/archive/2013/12/04/3457130.html

 

On iOS, it is not recommended to perform UI operations on non-main threads. There is a high chance that UI operations on non-main threads will cause the program to crash or have unexpected effects.

I didn't know this at first, I did a popup operation in the sub-thread, and the program went wrong!

The error reported is (EXC_BAD_ACCESS(code=2,address=0xcc), 0x1a0ad32: movl 204(%ecx), %edx ), I thought it was a memory leak caused by a null pointer, and I used a lot of methods, but this problem feels very stubborn , bothered me for many days.

Later, a big cow pointed me and asked me if I was doing this pop-up operation in a sub-thread. . . Until then I didn't understand where the problem was and the problem was solved smoothly. Sometimes there is a bug but I don't know what caused it. At this time, it is the most tangled. When the problem is clarified, the problem is not a problem. well, let's get back to business.

So how to handle UI operations in child threads? There are two ways:

One: In the child thread, add the dispatch_async function before the UI operation you need to perform, and you can transfer the work in the code block back to the main thread

dispatch_async(dispatch_get_main_queue(), ^ {  
             // Update UI operation  
             // .....   
        });

 The dispatch_async function is an asynchronous operation, and it can also be handled like this for more time-consuming operations: 

 
dispatch_async(dispatch_get_global_queue(0, 0), ^{  
    // The block of code that handles the time-consuming operation...  
      
    //Notify the main thread to refresh  
    dispatch_async(dispatch_get_main_queue(), ^{  
        //Callback or notify the main thread to refresh,  
    });  
      
});
 

dispatch_async starts an asynchronous operation, the first parameter is to specify a gcd queue, and the second parameter is to assign a program block that handles things to the queue.

 dispatch_get_global_queue(0, 0), which refers to the global queue.

Generally speaking, the system itself will have 3 queues.

global_queue,current_queue,以及main_queue.

Getting a global queue is taking two parameters, the first is the transaction handler block queue priority I assign. Divided into high and low and default, 0 is default 2 is high, -2 is low

 二:performSelectorOnMainThread

performSelectorOnMainThread refers to executing a method on the main thread, such as updating the UI interface after data download, etc.

  For example: use [self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO] in a child thread;

 

-(void)setupThread:(NSArray*)userInfor{  
  
   [NSThread detachNewThreadSelector:@selector(threadFunc:) toTarget:self withObject:(id)userInfor];  
  
}  
  
- (void)threadFunc:(id)userInfor{  
  
   NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init];  
  
   //. . . . processing that needs to be done.  
  
   //Return immediately after this thread ends  
  
  [self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO];  
  
  [pool release];  
  
}  
 

 

performSelectorOnMainThread notifies the main thread to execute the function endThread.

Again, do not perform any UI operations in the child thread, and do not refresh the interface. If you need to perform these operations, call the method in the main thread to execute through the two methods of dispatch_async or performSelectorOnMainThread.

 

I just encountered the icon of the button of the main window that needs to be changed when the sidebar is collapsed, and I encountered a crash. Then based on the above information, use

dispatch_async(dispatch_get_main_queue(), ^{  
            //Update UI operation  
            //.....  
        });

 Change UI crash can be resolved.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326220824&siteId=291194637