您的位置:首页 > 移动开发 > IOS开发

IOS中多线程应用实践

2013-05-29 11:16 211 查看
本文转载至:http://blog.sina.com.cn/s/blog_4c925dca01012e16.html

说到多线程的应用,应该也不算是什么新鲜的话题了。应该说在很多的开发语言中,都会用到。象java,.net,php,perl等语言中,我们都会看到,用到。当然,在ios的开发语言oc中,也同样如此。但是,没有做过ios开发,或不熟悉oc语言的人来说,也未必知道在oc中如何应用多线程的,有感如此,网络时空(阿堂)在应用一demo后,特此分享了,希望以后用oc来开发ios的多线程应用中的朋友可以参考一下,阿堂就感到很欣慰了!

下面,我们先来看一下demo的运行示意图,再来看看其中代码的具体应用!























每个子线程的实现的基本功能如下

1.每个子线程会将相应的计数器递增10次,更次iphone上的相应显示.

2.每次递增后,进入休眠0.5秒。

3.10次循环结束后,会更新总线程的计数器。

4.当用户指示杀掉这个独立线程,或者,杀掉所有线程 (通过点击 Stop All Counting),才会中止循环。

补充一点说明:

本demo中,即使点击停止当前计数操作了,如当前循环在还没有执行完10次计数,也不会停止的,只在当前10次循环结束了,才会真正停止.。。如需马上停止,还需要特殊处理一下,这里阿堂就不再说明了,有兴趣的朋友,可以稍加修改一下内容就可以了,因为本文,阿堂主要是介绍多线程在ios应用开发中一般的实际运用,不想说得太复杂了!

ThreadingViewController.h
#import <UIKit/UIKit.h>

@interface ThreadingViewController : UIViewController {
bool button1On;// keeps track if the Start Counting.. buttons are clicked
bool button2On;
bool button3On;
bool button4On;

int total; // keeps track of the total count
int countThread1; //keeps track of the count for each thread
int countThread2;
int countThread3;
int countThread4;

NSLock *myLock; //mutex used to create our Critical Section

IBOutlet UILabel *thread1Label; //Thread value labels
IBOutlet UILabel *thread2Label;
IBOutlet UILabel *thread3Label;
IBOutlet UILabel *thread4Label;

IBOutlet UILabel *totalCount; //Total thread count label
IBOutlet UILabel *updatedByThread; //Updated by thread label

IBOutlet UIButton *button1Title; // buttons titles that will be updated when
//clicked
IBOutlet UIButton *button2Title;
IBOutlet UIButton *button3Title;
IBOutlet UIButton *button4Title;
}

@property (retain,nonatomic) UIButton *button1Title; //getter and setters
@property (retain,nonatomic) UIButton *button2Title;
@property (retain,nonatomic) UIButton *button3Title;
@property (retain,nonatomic) UIButton *button4Title;

@property (retain,nonatomic) UILabel *totalCount; //getter and setters
@property (retain,nonatomic) UILabel *thread1Label;
@property (retain,nonatomic) UILabel *thread2Label;
@property (retain,nonatomic) UILabel *thread3Label;
@property (retain,nonatomic) UILabel *thread4Label;
@property (retain,nonatomic) UILabel *updatedByThread;

-(IBAction)launchThread1:(id)sender; //methods each button will trigger when
//clicked
-(IBAction)launchThread2:(id)sender;
-(IBAction)launchThread3:(id)sender;
-(IBAction)launchThread4:(id)sender;
-(IBAction)KillAllThreads:(id)sender;

-(void)thread1;
-(void)thread2;
-(void)thread3;
-(void)thread4;

-(void)displayThread1Counts:(NSNumber*)threadNumber;
-(void)displayThread2Counts:(NSNumber*)threadNumber;
-(void)displayThread3Counts:(NSNumber*)threadNumber;
-(void)displayThread4Counts:(NSNumber*)threadNumber;

-(void)countThreadLoops:(NSNumber*)threadNumber;

@end

ThreadingViewController.m
#import "ThreadingViewController.h"

@implementation ThreadingViewController
@synthesize totalCount;
@synthesize thread1Label;
@synthesize thread2Label;
@synthesize thread3Label;
@synthesize thread4Label;
@synthesize button1Title;
@synthesize button2Title;
@synthesize button3Title;
@synthesize button4Title;
@synthesize updatedByThread;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {

button1On = FALSE;
button2On = FALSE;
button3On = FALSE;
button4On = FALSE;
countThread1 = 0;
countThread2 = 0;
countThread3 = 0;
countThread4 = 0;
myLock = [[NSLock alloc]init];
[super viewDidLoad];
}

-(IBAction)launchThread1:(id)sender
{

if (!button1On)
{
button1On = TRUE;
[button1Title setTitle:@"Kill Counting 1" forState:UIControlStateNormal];

//工作线程
[self performSelectorInBackground:@selector(thread1) withObject:nil];
}
else
{
button1On = FALSE;
[button1Title setTitle:@"Start Counting 1" forState:UIControlStateNormal];

}
}

-(void)thread1
{

//启动一个线程时,实际上会脱离Cocoa框架。此时,需要我们来负责清理内存池,否则会出现内存泄露
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];// we are responsible for the memory pool
NSNumber *myNumber = [NSNumber numberWithInteger:1]; // the thread number for updating the display

while(button1On)
{
for (int x=0; x<10; x++)
{
[self performSelectorOnMainThread:@selector(displayThread1Counts:) //call the displayThread1Counts method
withObject:myNumber //can be used to to display thread number
waitUntilDone:YES]; //wait until the method returns
[NSThread sleepForTimeInterval:0.5]; //slow things down and sleep for 1/2 second
}
[self performSelectorOnMainThread:@selector(countThreadLoops:) //after 10 increments update the total count
withObject:myNumber //pass the thread number that did the updating
waitUntilDone:NO]; //don't need to wait. We have a critical section
}

[apool release];

}

-(void)displayThread1Counts:(NSNumber*)threadNumber
{
countThread1 += 1;
[thread1Label setText:[NSString stringWithFormat:@"%i", countThread1]];

}

-(IBAction)launchThread2:(id)sender
{
if (!button2On)
{
button2On = TRUE;
[button2Title setTitle:@"Kill Counting 2" forState:UIControlStateNormal];
[self performSelectorInBackground:@selector(thread2) withObject:nil];
}
else
{
button2On = FALSE;
[button2Title setTitle:@"Start Counting 2" forState:UIControlStateNormal];

}
}

-(void)thread2
{
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
NSNumber *myNumber = [NSNumber numberWithInteger:2];

while(button2On)
{
for (int x=0; x<10; x++)
{
[self performSelectorOnMainThread:@selector(displayThread2Counts:)
withObject:myNumber
waitUntilDone:YES];
[NSThread sleepForTimeInterval:.5];
}
[self performSelectorOnMainThread:@selector(countThreadLoops:)
withObject:myNumber
waitUntilDone:NO];
}

[apool release];

}

-(void)displayThread2Counts:(NSNumber*)threadNumber
{
countThread2 += 1;
[thread2Label setText:[NSString stringWithFormat:@"%i", countThread2]];

}

-(IBAction)launchThread3:(id)sender
{
if (!button3On)
{
button3On = TRUE;
[button3Title setTitle:@"Kill Counting 3" forState:UIControlStateNormal];
[self performSelectorInBackground:@selector(thread3) withObject:nil];
}
else
{
button3On = FALSE;
[button3Title setTitle:@"Start Counting 3" forState:UIControlStateNormal];

}
}

-(void)thread3
{
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
NSNumber *myNumber = [NSNumber numberWithInteger:3];

while(button3On)
{
for (int x=0; x<10; x++)
{
[self performSelectorOnMainThread:@selector(displayThread3Counts:)
withObject:myNumber
waitUntilDone:YES];
[NSThread sleepForTimeInterval:.5];
}
[self performSelectorOnMainThread:@selector(countThreadLoops:)
withObject:myNumber
waitUntilDone:NO];
}

[apool release];

}

-(void)displayThread3Counts:(NSNumber*)threadNumber
{
countThread3 += 1;
[thread3Label setText:[NSString stringWithFormat:@"%i", countThread3]];

}

-(IBAction)launchThread4:(id)sender
{
if (!button4On)
{
button4On = TRUE;
[button4Title setTitle:@"Kill Counting 4" forState:UIControlStateNormal];
[self performSelectorInBackground:@selector(thread4) withObject:nil];
}
else
{
button4On = FALSE;
[button4Title setTitle:@"Start Counting 4" forState:UIControlStateNormal];

}
}

-(void)thread4
{
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
NSNumber *myNumber = [NSNumber numberWithInteger:4];

while(button4On)
{
for (int x=0; x<10; x++)
{
[self performSelectorOnMainThread:@selector(displayThread4Counts:)
withObject:myNumber
waitUntilDone:YES];
[NSThread sleepForTimeInterval:.5];
}
[self performSelectorOnMainThread:@selector(countThreadLoops:)
withObject:myNumber
waitUntilDone:NO];
}

[apool release];

}

-(void)displayThread4Counts:(NSNumber*)threadNumber
{
countThread4 += 1;
[thread4Label setText:[NSString stringWithFormat:@"%i", countThread4]];

}

-(void)countThreadLoops:(NSNumber*)threadNumber
{

//保护临界区的互斥锁
[myLock lock]; //mutex to protect critical section
total += 10;
[self.totalCount setText:[NSString stringWithFormat:@"%i", total]];
[self.updatedByThread setText:[NSString stringWithFormat:@"Last updated by thread # %i",[threadNumber integerValue]]];

//确保完成unLock,否则会创建一个死锁
[myLock unlock]; //make sure you perform unlock or you will create a deadlock condition
}

-(IBAction)KillAllThreads:(id)sender
{
button1On = FALSE;
button2On = FALSE;
button3On = FALSE;
button4On = FALSE;

[button1Title setTitle:@"Start Counting 1" forState:UIControlStateNormal];
[button2Title setTitle:@"Start Counting 2" forState:UIControlStateNormal];
[button3Title setTitle:@"Start Counting 3" forState:UIControlStateNormal];
[button4Title setTitle:@"Start Counting 4" forState:UIControlStateNormal];
}

- (void)dealloc {
[totalCount release];
[thread1Label release];
[thread2Label release];
[thread3Label release];
[thread4Label release];
[button1Title release];
[button2Title release];
[button3Title release];
[button4Title release];
[updatedByThread release];
[myLock release];
[super dealloc];
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: