iPhone开发之多线程NSThread和NSInvocationOperation

移动开发 iOS
多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法。

多线程编程是防止主线程堵塞,增加运行效率等等的***方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法。

本次介绍NSOperation的子集,简易方法的NSInvocationOperation:

 

 

  1. @implementation MyCustomClass   
  2.  
  3.  -(void)launchTaskWithData:(id)data   
  4.  
  5.  {   
  6.  
  7.    //创建一个NSInvocationOperation对象,并初始化到方法;   
  8.  
  9.     //在这里,selector参数后的值是你想在另外一个线程中运行的方法(函数,Method);   
  10.  
  11.    //在这里,object后的值是想传递给前面方法的数据   
  12.  
  13.    NSInvocationOperation *theOp = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(myTashMethod:) object:data];   
  14.  
  15.    //下面将我们建立的操作"Operation"加入到本地程序的共享的队列中(加入后方法就会立刻被执行)   
  16.  
  17.    //更多的时候是由我们自己建立“操作”队列   
  18.  
  19.    [[MyAppDelegate sharedOperationQueue] addOperation:theOp];   
  20.  
  21.  }   
  22.  
  23.     
  24.  
  25.  //这个是真正运行在另外一个线程的“方法”   
  26.  
  27.     
  28.  
  29.  - (void)myTaskMethod:(id)data   
  30.  
  31. {   
  32.     // Perform the task.   
  33.  
  34.  }   
  35.  
  36.  @end   
  37.  
  38.     
  39.  
  40. //一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。   
  41.  
  42.  //下面是建立并初始化一个操作队列:   
  43.  
  44.  @interface MyViewController : UIViewController {   
  45.  
  46.     
  47.  
  48.     NSOperationQueue* operationQueue;   
  49.  
  50.    //在头文件中声明该队列   
  51.  
  52. }   
  53.  
  54.  @end   
  55.  
  56.     
  57.  
  58.  @implementation MyViewController   
  59.  
  60.     
  61.  
  62.  -(id)init   
  63.  {   
  64.  
  65.   self = [super init];   
  66.  
  67.    if (self) {   
  68.  
  69.       //初始化操作队列   
  70.  
  71.       operationQueue = [[NSOperationQueue alloc] init];   
  72.  
  73.       [operationQueue setMaxConcurrentOperationCount:1];   
  74.  
  75.        //在这里限定了该队列只同时运行一个线程   
  76.  
  77.       //这个队列已经可以使用了   
  78.  
  79.    }   
  80.  
  81.     return self;   
  82.  
  83. }   
  84.  
  85.     
  86.  
  87.  - (void)dealloc   
  88.  
  89.  {   
  90.  
  91.     [operationQueue release];   
  92.  
  93.     [super dealloc];   
  94.  
  95. }   
  96.  
  97.  @end   
  98.  
  99. //简单介绍之后,其实可以发现这种方法是非常简单的。很多的时候我们使用多线程仅仅是为了防止主线程堵塞,而NSInvocationOperation就是最简单的多线程编程,在iPhone编程中是经常被用到的。   
  100.  
  101.     
  102.  
  103. /////////////////////////////////////////////////////////////   
  104.  
  105.  //在主线程里加入一个loading画面……   
  106.  
  107.  {   
  108.  
  109.     [window addSubview:view_loading];   
  110.  
  111.     //另一个新的线程,可能需要时间进行后台处理,为了防止主程序在这段时间静止等待,将后台处理放在主线程之外的线程执行,执行完以后,通知主线程更新数据。   
  112.  
  113.     [NSThread detachNewThreadSelector:@selector:(init_backup:) toTarget:self withObject:nil];   
  114.  
  115.  }   
  116.  
  117.     
  118.  
  119.      
  120.  
  121.  //可以通过performSelectorOhMainThread更新UI元素,比如设置进度条等等。***消除loading画面,载入主View。   
  122.  
  123.  -(void)init_backup:(id)sender   
  124.  
  125.  {   
  126.  
  127.     NSAutorelease* pool = [[NSAutoreleasePool alloc] init];   
  128.  
  129.    //新建的线程需要一个自动释放池对线程中申请的内存进行管理   
  130.  
  131.     int i = status;   
  132.  
  133.     [self performSelectorOnMainThread:@selector:(show_loading:) wiwithObject::[NSNumber numberWithInt:i] waitUntil Done:NO];   
  134.  
  135.     [view_loading removeFromSuperview];   
  136.  
  137.     [window addSubview:tabcontroller_main.view];   
  138.  
  139.    [pool release];   
  140.  

利用iphone的多线程实现和线程同步

    从接口的定义中可以知道,NSThread和大多数iphone的接口对象一样,有两种方式可以初始化:

    一种使用initWithTarget :(id)target selector:(SEL)selector object:(id)argument,但需要负责在对象的retain count为0时调用对象的release方法清理对象。

   另一种则使用所谓的convenient method,这个方便接口就是detachNewThreadSelector,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。

  1. #import <UIKit/UIKit.h>   
  2.  
  3.  @interface SellTicketsAppDelegate : NSObject <UIApplicationDelegate>    
  4.  
  5. {   
  6.  
  7.      
  8.  
  9.     int tickets;   
  10.  
  11.     int count;   
  12.  
  13.      NSThread* ticketsThreadone;   
  14.  
  15.     NSThread* ticketsThreadtwo;   
  16.  
  17.     NSCondition* ticketsCondition;   
  18.  
  19.      UIWindow *window;   
  20.  
  21.  }   
  22.  
  23.  @property (nonatomic, retain) IBOutlet UIWindow *window;   
  24.  
  25.  @end   
  26.  
  27.    
  28.  
  29.  //SellTicketsAppDelegate.m   
  30.  
  31.  #import "SellTicketsAppDelegate.h"   
  32.  @implementation SellTicketsAppDelegate   
  33.  
  34.  @synthesize window;   
  35.  
  36.  - (void)applicationDidFinishLaunching:(UIApplication *)application    
  37.  
  38.  {   
  39.  
  40.    
  41.  
  42.    tickets = 100;   
  43.  
  44.     count = 0;   
  45.  
  46.     // 锁对象   
  47.  
  48.     ticketCondition = [[NSCondition alloc] init];   
  49.  
  50.     ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];   
  51.  
  52.    [ticketsThreadone setName:@"Thread-1"];   
  53.  
  54.    [ticketsThreadone start];   
  55.  
  56.     
  57.  
  58.     ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];   
  59.  
  60.     [ticketsThreadtwo setName:@"Thread-2"];   
  61.  
  62.     [ticketsThreadtwo start];      
  63.  
  64.     
  65.  
  66.     //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];   
  67.  
  68.     // Override point for customization after application launch   
  69.  
  70.     [window makeKeyAndVisible];   
  71.  
  72.  }   
  73.  
  74.      
  75.  
  76.  - (void)run{   
  77.  
  78.     while (TRUE) {   
  79.  
  80.      //上锁   
  81.  
  82.       [ticketsCondition lock];   
  83.  
  84.       if(tickets > 0)   
  85.  
  86.      {   
  87.  
  88.           [NSThread sleepForTimeInterval:0.5];   
  89.  
  90.          count = 100 - tickets;   
  91.  
  92.          NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);   
  93.  
  94.           tickets--;   
  95.  
  96.       }   
  97.  
  98.       else  
  99.  
  100.       {   
  101.  
  102.            break;   
  103.  
  104.       }   
  105.  
  106.       [ticketsCondition unlock];   
  107.  
  108.  }   
  109.  
  110.      
  111.  
  112.  -(void)dealloc{   
  113.  
  114.      [ticketsThreadone release];   
  115.  
  116.      [ticketsThreadtwo release];   
  117.  
  118.      [ticketsCondition release];   
  119.  
  120.      [window release];   
  121.  
  122.      [super dealloc];   
  123.  
  124.  }   
  125.  
  126. @end  
责任编辑:张叶青 来源: 开源社区
相关推荐

2011-08-18 17:07:23

IOS开发多线程NSInvocatio

2011-08-12 10:09:23

iPhone开发多线程

2016-04-12 09:48:24

nsthread多线程ios

2023-06-13 13:39:00

多线程异步编程

2013-06-07 16:30:08

iOS多线程iOS开发NSThread

2023-06-06 08:17:52

多线程编程Thread类

2023-06-05 07:56:10

线程分配处理器

2011-07-21 11:12:58

iPhone 线程 多线程

2011-06-02 17:27:49

iphone 多线程

2011-08-08 13:50:29

iPhone开发 NSOperatio 多线程

2021-03-05 07:38:52

C++线程编程开发技术

2011-08-01 12:53:25

iPhone 多线程 线程

2021-06-29 07:47:23

多线程协作数据

2011-07-08 16:43:46

iPhone Cocoa 多线程

2009-08-17 16:56:51

C#多线程控制进度条

2011-06-07 17:35:39

iphone 多线程

2018-04-20 14:11:27

多线程死锁乐观锁

2016-10-09 20:15:30

多线程多进程

2023-11-03 07:50:01

2011-08-09 14:24:18

iPhone多线程线程
点赞
收藏

51CTO技术栈公众号