在多线程中进行UI操作--ios学习笔记
2013-08-20 14:26
483 查看
iOS 上不建议在非主线程进行UI操作,在非主线程进行UI操作有很大几率会导致程序崩溃,或者出现预期之外的效果。
我开始不知道这一点,在子线程中进行了弹窗操作,结果程序就出问题了!
报的错误是(EXC_BAD_ACCESS(code=2,address=0xcc),0x1a0ad32: movl 204(%ecx), %edx ),我以为是空指针导致的内存泄露,用了很多方法,但这问题感觉很顽固,困扰了我很多天。
后来有位大牛指点了我,问我是不是在子线程进行这个弹窗操作。。。直到此时我才明白问题出在哪里,问题顺利解决。有时候出现bug却不知道是哪引起的,这时是最纠结的,等明确了问题所在,问题就不是问题了。好了,言归正传。
那么在子线程中的UI操作如何处理呢?有两种方法:
一:在子线程,你需要进行的UI操作前添加dispatch_async函数,即可将代码块中的工作转回到主线程
dispatch_async函数是异步操作,对于比较耗时的操作也可以这样处理:
dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。
dispatch_get_global_queue(0, 0),指用了全局队列。
一般来说系统本身会有3个队列。
global_queue,current_queue,以及main_queue.
获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低
二:performSelectorOnMainThread
performSelectorOnMainThread是指在主线程上执行某个方法,比如数据下载后,更新UI界面等操作
例如:在子线程中使用[self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO];
performSelectorOnMainThread通知主线程执行函数endThread。
再次强调子线程内不要进行任何UI操作,不要刷新界面。如果需要进行这些操作,通过dispatch_async或performSelectorOnMainThread这两种方法,调出主线程中的方法去执行。
我开始不知道这一点,在子线程中进行了弹窗操作,结果程序就出问题了!
报的错误是(EXC_BAD_ACCESS(code=2,address=0xcc),0x1a0ad32: movl 204(%ecx), %edx ),我以为是空指针导致的内存泄露,用了很多方法,但这问题感觉很顽固,困扰了我很多天。
后来有位大牛指点了我,问我是不是在子线程进行这个弹窗操作。。。直到此时我才明白问题出在哪里,问题顺利解决。有时候出现bug却不知道是哪引起的,这时是最纠结的,等明确了问题所在,问题就不是问题了。好了,言归正传。
那么在子线程中的UI操作如何处理呢?有两种方法:
一:在子线程,你需要进行的UI操作前添加dispatch_async函数,即可将代码块中的工作转回到主线程
dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... });
dispatch_async函数是异步操作,对于比较耗时的操作也可以这样处理:
dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 处理耗时操作的代码块... //通知主线程刷新 dispatch_async(dispatch_get_main_queue(), ^{ //回调或者说是通知主线程刷新, }); });
dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。
dispatch_get_global_queue(0, 0),指用了全局队列。
一般来说系统本身会有3个队列。
global_queue,current_queue,以及main_queue.
获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低
二:performSelectorOnMainThread
performSelectorOnMainThread是指在主线程上执行某个方法,比如数据下载后,更新UI界面等操作
例如:在子线程中使用[self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO];
-(void)setupThread:(NSArray*)userInfor{ [NSThread detachNewThreadSelector:@selector(threadFunc:) toTarget:self withObject:(id)userInfor]; } - (void)threadFunc:(id)userInfor{ NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init]; //。。。。需要做的处理。 //这里线程结束后立即返回 [self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO]; [pool release]; }
performSelectorOnMainThread通知主线程执行函数endThread。
再次强调子线程内不要进行任何UI操作,不要刷新界面。如果需要进行这些操作,通过dispatch_async或performSelectorOnMainThread这两种方法,调出主线程中的方法去执行。
相关文章推荐
- 在多线程中进行UI操作--ios学习笔记
- 在多线程中进行UI操作--ios学习笔记
- ios学习笔记之UI篇(三):操作表单(action sheet)和警告(alert)
- iOS学习笔记-119.多线程18——NSOperationQueue自定义NSOperation执行一个操作的取消
- IOS 开发学习笔记-基础 UI(十)九宫格布局,块动画,字典转模型,Xib使用
- iOS学习笔记(十五)——数据库操作(SQLite)
- iOS学习笔记——数据库操作(使用FMDB)
- iOS学习笔记(十六)——数据库操作(使用FMDB)
- IOS学习笔记 多线程基本理论基础(1)
- iOS 学习笔记 多线程
- iOS学习笔记(十六)——数据库操作(使用FMDB)
- iOS学习笔记-102.多线程01——iOS中多线程的实现方案
- IOS学习笔记25—HTTP操作之ASIHTTPRequest(一)
- lr学习笔记--controller进行并发操作,多用户单循环、多用户多循环
- iOS学习笔记<20> iOS中的GCD多线程模型 & ios事件的通知方法
- Android(java)学习笔记186:对ListView等列表组件中数据进行增、删、改操作
- IOS学习笔记39——拍照、从相册选图并对图片进行裁剪
- iOS阶段学习第16天笔记(Category-NSSet-SEL-NSIndexSet 操作)
- iOS-学习笔记-UI-第八天
- iOS学习笔记—— UIActivityIndicatorView 和 UIProgressView 的使用