iphone 线程总结— detachNewThreadSelector的使用
2013-10-21 18:08
423 查看
不管是iphone中还是其他的操作系统,多线程在各种编程语言中都是难点,很多语言中实现起来很麻烦,objective-c虽然源于c,但其多线程编程却相当简单,可以与java相媲美。多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。
一、线程创建与启动
线程创建主要有二种方式:
当然,还有一种比较特殊,就是使用所谓的convenientmethod,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。这个方法的接口是:
前两种方法创建后,需要手机启动,启动的方法是:
二、线程的同步与锁
要说明线程的同步与锁,最好的例子可能就是多个窗口同时售票的售票系统了。我们知道在java中,使用synchronized来同步,而iphone虽然没有提供类似java下的synchronized关键字,但提供了NSCondition对象接口。查看NSCondition的接口说明可以看出,NSCondition是iphone下的锁对象,所以我们可以使用NSCondition实现iphone中的线程安全。这是来源于网上的一个例子:
SellTicketsAppDelegate.h文件
三、线程的交互
线程在运行过程中,可能需要与其它线程进行通信,如在主线程中修改界面等等,可以使用如下接口:
由于在本过程中,可能需要释放一些资源,则需要使用NSAutoreleasePool来进行管理,如:
performSelectorOnMainThread通知主线程执行函数endThread。也可以使用performSelector:onThread:withObject:waitUntil通知某线程执行线程结束后的处理。线程内不要刷新界面。如果需要刷新界面,通过performSelectorOnMainThread,调出主线程中的方法去刷新。例如,启动一个线程下载图片://启动线程[NSThreaddetachNewThreadSelector:@selector(downloadImage:)toTarget:selfwithObject:url];//线程函数
首先我们需要创建一个线程有两种方法:-(id)initWithTarget:(id)targetselector:(SEL)selectorobject:(id)argument+(void)detachNewThreadSelector:(SEL)aSelectortoTarget:(id)aTargetwithObject:(id)anArgument因为第二种方法不用对线程进行清理,所以我们常用第二种哦个方法。[NSThreaddetachNewThreadSelector:@selector(new:)toTarget:selfwithObject:nil];-(void)new:(id)sender{[_myConditionlock];//performSelectorInBackgroud主要进行逻辑上处理[selfperformSelectorInBackgroud:@selector(doInBackgroud:)withObject:nil];//perfomSelectorOnMainThread主要进行界面UI上的处理[selfperfomSelectorOnMainThread:@selector(doOnMain:)withObject:nil];//[NSThreadsleepForTimeInterval:n];[_myConditionsignal];[_myConditionunlock];[NSThreadexit];return;}
[/code]
一、线程创建与启动
线程创建主要有二种方式:
(id)init;//designatedinitializer (id)initWithTarget:(id)targetselector: (SEL)selectorobject:(id)argument;
当然,还有一种比较特殊,就是使用所谓的convenientmethod,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。这个方法的接口是:
(void)detachNewThreadSelector: (SEL)aSelectortoTarget: (id)aTargetwithObject: (id)anArgument
前两种方法创建后,需要手机启动,启动的方法是:
(void)start;
二、线程的同步与锁
要说明线程的同步与锁,最好的例子可能就是多个窗口同时售票的售票系统了。我们知道在java中,使用synchronized来同步,而
SellTicketsAppDelegate.h文件
//SellTicketsAppDelegate.h import<UIKit/UIKit.h> @interfaceSellTicketsAppDelegate:NSObject<UIApplicationDelegate>{ inttickets; intcount; NSThread*ticketsThreadone; NSThread*ticketsThreadtwo; NSCondition*ticketsCondition; UIWindow*window; } @property(nonatomic,retain)IBOutletUIWindow*window; @end SellTicketsAppDelegate.m文件 //SellTicketsAppDelegate.m import"SellTicketsAppDelegate.h" @implementationSellTicketsAppDelegate @synthesizewindow; -(void)applicationDidFinishLaunching:(UIApplication*)application{ tickets=100; count=0; //锁对象 ticketCondition=[[NSConditionalloc]init]; ticketsThreadone=[[NSThreadalloc]initWithTarget:selfselector:@selector(run)object:nil]; [ticketsThreadonesetName:@"Thread-1"]; [ticketsThreadonestart]; ticketsThreadtwo=[[NSThreadalloc]initWithTarget:selfselector:@selector(run)object:nil]; [ticketsThreadtwosetName:@"Thread-2"]; [ticketsThreadtwostart]; //[NSThreaddetachNewThreadSelector:@selector(run)toTarget:selfwithObject:nil]; //Overridepointforcustomizationafterapplicationlaunch [windowmakeKeyAndVisible]; } -(void)run{ while(TRUE){ //上锁 [ticketsConditionlock]; if(tickets>0){ [NSThreadsleepForTimeInterval:0.5]; count=100-tickets; NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThreadcurrentThread]name]); tickets--; }else{ break; } [ticketsConditionunlock]; } } -(void)dealloc{ [ticketsThreadonerelease]; [ticketsThreadtworelease]; [ticketsConditionrelease]; [windowrelease]; [superdealloc]; } @end
三、线程的交互
线程在运行过程中,可能需要与其它线程进行通信,如在主线程中修改界面等等,可以使用如下接口:
(void)performSelectorOnMainThread: (SEL)aSelectorwithObject: (id)argwaitUntilDone: (BOOL)wait
由于在本过程中,可能需要释放一些资源,则需要使用NSAutoreleasePool来进行管理,如:
(void)startTheBackgroundJob{ NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init]; //todosomethinginyourthreadjob ... [selfperformSelectorOnMainThread:@selector(makeMyProgressBarMoving)withObject:nilwaitUntilDone:NO]; [poolrelease]; }
举例说明怎么简单的创建一个子线程。用到的类是NSThread类,这里使用detachNewTheadSelector:toTagaet:withObject创建一个线程。函数setupThread:(NSArray*)userInfor。通过userInfor将需要的数据传到线程中。函数定义:[代码]c#/cpp/oc代码:
[code]01 | -( void )setupThread:(NSArray*)userInfor{ |
02 |
03 | [NSThread detachNewThreadSelector:@selector(threadFunc:)toTarget:selfwithObject:(id)userInfor]; |
04 |
05 | } |
06 |
07 | - ( void )threadFunc:(id)userInfor{ |
08 |
09 | NSAutoreleasePool*pool =[[NSAutoreleasePoolalloc]init]; |
10 |
11 | //。。。。需要做的处理。 |
12 |
13 | //这里线程结束后立即返回 |
14 |
15 | [self performSelectorOnMainThread:@selector(endThread)withObject:nilwaitUntilDone:NO]; |
16 |
17 | [pool release]; |
18 |
19 | } |
[代码]c#/cpp/oc代码:
01 | - ( void ) downloadImage:(NSString*)url{ |
02 |
03 | _subThreed =[NSThreadcurrentThread]; |
04 |
05 | self.uploadPool =[[NSAutoreleasePoolalloc]init]; |
06 | self.characterBuffer =[NSMutableDatadata]; |
07 | done =NO; |
08 | [[NSURLCache sharedURLCache]removeAllCachedResponses]; |
09 |
10 | NSMutableURLRequest *theRequest=[NSMutableURLRequestrequestWithURL:[NSURLURLWithString:url]]; |
11 |
12 | self.connection =[[NSURLConnectionalloc]initWithRequest:theRequest delegate :self]; |
13 | [self performSelectorOnMainThread:@selector(httpConnectStart)withObject:nilwaitUntilDone:NO]; |
14 | if (connection !=nil){ |
15 | do { |
16 | [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopModebeforeDate:[NSDatedistantFuture]]; |
17 | } while (!done); |
18 | } |
19 |
20 | self.photo =[UIImageimageWithData:characterBuffer]; |
21 |
22 |
23 | //下载结束,刷新 |
24 | [self performSelectorOnMainThread:@selector(fillPhoto)withObject:nilwaitUntilDone:NO]; |
25 |
26 | // Releaseresourcesusedonlyinthisthread. |
27 | self.connection =nil; |
28 | [uploadPool release]; |
29 | self.uploadPool =nil; |
30 |
31 | _subThreed =nil; |
32 | } |
33 |
34 |
35 |
36 | #pragma markNSURLConnectionDelegatemethods |
37 |
38 | /* |
39 | Disable |
40 | */ |
41 | - (NSCachedURLResponse*)connection:(NSURLConnection*)connectionwillCacheResponse:(NSCachedURLResponse*)cachedResponse{ |
42 |
43 | return nil; |
44 | } |
45 |
46 | // |
47 | - ( void )connection:(NSURLConnection |
48 | done |
49 | [self |
50 | [characterBuffer setLength:0]; |
51 |
52 | } |
53 |
54 | // |
55 | - ( void )connection:(NSURLConnection |
56 | // |
57 |
58 | [characterBuffer appendData:data]; |
59 |
60 | } |
61 |
62 | - ( void )connectionDidFinishLoading:(NSURLConnection |
63 |
64 | [self |
65 | // |
66 | done |
67 |
68 | } |
[/code]
相关文章推荐
- iphone 线程总结— detachNewThreadSelector的使用
- iphone 线程总结— detachNewThreadSelector的使用
- iphone 线程总结— detachNewThreadSelector的使用
- iphone 线程总结— detachNewThreadSelector的使用
- iphone 线程总结— detachNewThreadSelector的使用
- iphone 线程总结— detachNewThreadSelector的使用
- iphone线程中使用异步网络的悲催经历
- Qt4.8 QtConcurrent 线程使用总结
- iphone 个人使用总结
- IOS线程的使用 performSelectorOnMainThread
- iphone线程中使用异步网络的问题,以及如何用NSRunLoop来解决
- Drawable基础知识总结----drawable标签selector的使用
- iphone线程中使用异步网络的悲催经历
- java线程使用总结
- iphone SQLite3使用总结
- Android中线程的使用与总结
- linux c之使用pthread_create创建线程pthread_join等待线程和pthread_exit终止线程总结
- android进程和线程使用总结
- IOS SEL (@selector) 原理及使用总结(一)
- iphone SQLite3使用总结