`

ios 任务、线程、定时器

 
阅读更多

一:operations(任务)

 

cocoa提供了三种不同的operations

 

1:Block operations(NSBlockOperation
These facilitate the execution of one or more block objects.

 

 

#import <UIKit/UIKit.h>
@interface OperationsAppDelegate : NSObject <UIApplicationDelegate> {
	UIWindow *window;
	NSBlockOperation *simpleOperation;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) NSBlockOperation *simpleOperation;

@end

 

#import "OperationsAppDelegate.h"

@implementation OperationsAppDelegate
@synthesize window;
@synthesize simpleOperation;

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	/* Here is our block */
	NSBlockOperation *newBlockOperation = [NSBlockOperation blockOperationWithBlock:^{
							NSLog(@"Main Thread = %@", [NSThread mainThread]);
							NSLog(@"Current Thread = %@", [NSThread currentThread]);
							NSUInteger counter = 0;
							for (counter = 0;counter < 1000;counter++){
								NSLog(@"Count = %lu", (unsigned long)counter);
							}
								}];

	/* Make sure we keep the reference somewhere */
	self.simpleOperation = newBlockOperation;
	
	/* Start the operation */
	[self.simpleOperation start];

	/* Print something out just to test if we have to wait
	for the block to execute its code or not */
	
	NSLog(@"Main thread is here");
	[window makeKeyAndVisible];
	return YES;
}


- (void)dealloc {
	[simpleOperation release];
	[window release];
	[super dealloc];
}

@end

 

 


2:Invocation operations(NSInvocationOperation
These allow you to invoke a method in another, currently existing object.

 

NSNumber *simpleObject = [NSNumber numberWithInteger:123];

NSInvocationOperation *newOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(simpleOperationEntry:) object:simpleObject];

[newOperation  start];

 

 

调用start方法执行改任务

 

#import <UIKit/UIKit.h>
@interface OperationsAppDelegate : NSObject <UIApplicationDelegate> {
	UIWindow *window;
	NSInvocationOperation *simpleOperation;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) NSInvocationOperation *simpleOperation;

@end

 

- (void) simpleOperationEntry:(id)paramObject{

	NSLog(@"Parameter Object = %@", paramObject);
	NSLog(@"Main Thread = %@", [NSThread mainThread]);
	NSLog(@"Current Thread = %@", [NSThread currentThread]);
}

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

	NSNumber *simpleObject = [NSNumber numberWithInteger:123];
	NSInvocationOperation *newOperation =[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(simpleOperationEntry:) object:simpleObject];
	self.simpleOperation = newOperation;
	[newOperation release];

	[self.simpleOperation start];
	[window makeKeyAndVisible];
	return YES;
}

- (void)dealloc {

	[simpleOperation release];
	[window release];
	[super dealloc];
}

 

 

 

 

 

 


3:Plain operations(简单的任务)NSOperation的子类


These are plain operation classes that need to be subclassed. The code to be executed
will be written inside the main method of the operation object.

 

 

@interface MyTask : NSOperation { 
    int operationId; 
}

@property int operationId;

@end

 

这里的operationId属性不是必须的

 

@implementation MyTask

@synthesize operationId;

- (void)main{ 
    NSLog(@"task %i run … ",operationId); 
    [NSThread sleepForTimeInterval:10]; 
    NSLog(@"task %i is finished. ",operationId); 
}

@end

 

 

必须
- (void)main;方法,[MyTask start]是执行main方法

 

 

二:任务队列(NSOperationQueue)

 

NSOperationQueue *newOperationQueue = [[NSOperationQueue alloc] init];
[ newOperationQueue  addOperation:Operation];

 

 

以上三种Operation都可以添加到NSOperationQueue中,添加后立即被执行。

 

NSOperationQueue 可以设置最大并行执行任务数。默认值为-1无限制。

 

 

三:多个任务之间存在依赖关系

 

设置方式:

[self.firstOperation addDependency:self.secondOperation];

 

dependency:附属的意思

 

把secondOperation做为firstOperation的附属。因此先执行secondOperation,再执行firstOperation 。

 

 

四:延时执行某个方法

 

1:performSelector:withObject:afterDelay:

 

 

- (void) connectionHasFailedWithError:(NSError *)paramError onRemoteURL:(NSURL *)paramRemoteURL{
	/* We failed to download the file. Attempt to download it again after 3 seconds */
	[self performSelector:@selector(attemptToDownloadRemoteURL:) withObject:paramRemoteURL afterDelay:3.0f];
}

- (void) attemptToDownloadRemoteURL:(NSURL *)paramRemoteURL{
	/* Attempt to download the remote file again here by initializing
	a new connection ... */
}

 

该方法只能接受一个参数。如果需要传递多个参数怎么办呢???

     让selector调用的方法接受的参数类型修改为Dictionary类型。

 

 

(1)如果调用的selector不接受参数则,withObject:nil

(2) 通过performSelector:withObjcet:afterDelay调用的方法不能有返回值

 

 

2:取消延时执行的方法

 

(1)cancelPreviousPerformRequestsWithTarget: 

(2) cancelPreviousPerformRequestsWithTarget:selector:object:

 

 

五:NSTimer

 

1:scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

 

2:invalidate

调用invalidate方法,不仅是释放NSTimer,还释放userinfo对象。
如果repeats设置为NO,NSTimer在调用完成之后就知道失效,随即释放userinfo对象

 

3:scheduledTimerWithTimeInterval:invocation:repeats:

 

- (void) startPainting{
 	SEL selectorToCall = @selector(paint:);
 	NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selectorToCall];
 	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
	[invocation setTarget:self];
	[invocation setSelector:selectorToCall];

/* Start a scheduled timer now */
NSTimer *newTimer =[NSTimer scheduledTimerWithTimeInterval:1.0
						invocation:invocation
						   repeats:YES];

	self.paintingTimer = newTimer;
}

 

 4:timerWithTimeInterval:target:selector:userInfo:repeats:

   (用该方式,需要把timer添加到runloop中)

 

- (void) startPainting{
	NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0
						    target:self
						  selector:@selector(paint:)
						  userInfo:nil
						   repeats:YES];

	self.paintingTimer = newTimer;

	[[NSRunLoop currentRunLoop] addTimer:self.paintingTimer forMode:NSDefaultRunLoopMode];
}

 

5:timerWithTimeInterval:invocation:repeats:

  (用该方式,需要把timer添加到runloop中)

- (void) startPainting{ 
	SEL selectorToCall = @selector(paint:);
 	NSMethodSignature *methodSignature =[[self class] instanceMethodSignatureForSelector:selectorToCall];
 	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];

	[invocation setTarget:self];
	[invocation setSelector:selectorToCall];
	NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0
						invocation:invocation
						   repeats:YES];
	self.paintingTimer = newTimer;
 	[[NSRunLoop currentRunLoop] addTimer:self.paintingTimer
				     forMode:NSDefaultRunLoopMode];
}

 

 

6:NSTimer 响应函数定义格式

 

并需有一个NSTimer *类型的参数

 

- (void) paint:(NSTimer *)paramTimer{
	/* Do something here */
	NSLog(@"Painting");
}

 

 

 

六:NSThread

 

1:initWithTarget:selector:object:

 

2:detachNewThreadSelector:toTarget: withObject:

 

以上两种方式,selector调用的函数,必须声明自己的NSAutoreleasePool

 

 

3:performSelectorInBackground: withObject:

     一个简单的方法来创建线程,而无需直接处理线程。

[self performSelectorInBackground:@selector(thirdCounter) withObject:nil];

 

4:start

调用start方法启动线程

 

5:cancel

调用cancel方法,并把变量赋值为nil

 

6:cancel vs exit

 

对于线程调用cancel方法停止,不要调用exit,因为exit方法没有给线程清理自己并释放资源的时间

 

7:线程的内存泄露

 

 - (void) newThreadEntryPoint{
	/* A thread without an autorelease pool to test the following code */
	//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	/* This WILL cause a memory leak */
	[self performSelector:@selector(allocateSomething)];

	/* This will NOT cause a memory leak */
	[self performSelectorOnMainThread:@selector(allocateSomething)
				withObject:nil
			     waitUntilDone:YES];
	//[pool release];
}

- (void) allocateSomething{
	NSBundle *mainBundle = [NSBundle mainBundle];
	NSString *imagePath = [mainBundle pathForResource:@"MyImage" ofType:@"png"];
	NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
	UIImage *myImage = [[[UIImage alloc] initWithData:imageData] autorelease];
	/* Do something with the image here */
}

- (void)viewDidLoad {

	[NSThread detachNewThreadSelector:@selector(newThreadEntryPoint)
				 toTarget:self
			       withObject:nil];
}

 

 

UIImage *myImage = [[[UIImage alloc] initWithData:imageData] autorelease];-------------自动释放池的范围

 

/* This WILL cause a memory leak */
[self performSelector:@selector(allocateSomething)];

调用改方法myImage 对象被添加进该新建线程的自动释放池,但因为在这里没有声明NSAutoreleasePool 造成内存泄露

 


 /* This will NOT cause a memory leak */
[self performSelectorOnMainThread:@selector(allocateSomething)
withObject:nil
     waitUntilDone:YES];

 

调用改方法myImage 对象被放进主线程的自动释放池,在主线程销毁是被自动释放

 

 

 


 

分享到:
评论

相关推荐

    ios 多线程编程指南

    RunLoop是iOS中管理线程事件循环的一种机制,它监听和处理异步事件,如输入源和定时器事件。 #### 3.1 RunLoop剖析 RunLoop模式、输入源是RunLoop工作的基础。通过配置RunLoop,可以让线程在没有任务时处于休眠状态...

    iOS开发学习之iOS多线程和RunLoop.pdf

    在iOS开发中,多线程编程是一个非常重要的概念,它允许应用程序同时执行多个操作,而不会相互干扰,从而提高程序的性能和响应能力。另外,RunLoop是iOS中一个非常重要的概念,它是事件接收循环,用于处理异步事件,...

    ios多线程指南

    除了传统的多线程外,iOS还提供了其他几种执行并发任务的方法: - **GCD (Grand Central Dispatch)**:现代iOS并发框架,简化了线程管理和调度。 - **NSOperation** 和 **NSOperationQueue**:面向对象的并发管理...

    IOS两个精典的关于多线程的例子代码

    4. **NSRunLoop**:在新线程中运行事件循环,通常用于网络请求、定时器等持续监听的任务。 二、NSThread的使用 `NSThread`是iOS中处理多线程的一种基本方式,它的主要方法包括: 1. **+ (void)...

    IOS多线程资料整理

    在iOS开发中,多线程是一项关键的技术,它允许应用程序同时执行多个任务,提升用户体验。本文将深入探讨iOS多线程的基本概念、线程管理以及线程间的通信机制。 首先,我们来理解线程的基本概念。线程是操作系统分配...

    iOS多线程变成指南

    ### iOS多线程编程指南知识点概述 #### 一、多线程编程概念及重要性 - **多线程定义**:多线程是指在单一应用程序内同时运行多个代码执行路径的技术。 - **目的**:提高应用程序响应速度和效率,通过并行处理任务...

    ios 基本线程测试

    这里我们关注的是“ios基本线程测试”,特别是使用GCD(Grand Central Dispatch)进行带参数的线程操作,并在任务完成时通知主线程。GCD是Apple推出的一种异步编程解决方案,它在iOS和macOS系统中被广泛使用。 **...

    IOS 多线程文档

    ### IOS多线程知识点概述 #### 一、多线程编程的基本概念与术语 ##### 1.1 什么是多线程 多线程是操作系统的一种功能,它允许在一个应用程序内部同时运行多个执行路径,每个执行路径称为一个线程。通过多线程,...

    ios 时间定时器 NSTimer应用demo

    在iOS开发中,`NSTimer`是一个非常重要的类,它允许开发者在指定的时间间隔后执行某段代码,或者定期重复执行某任务。本教程将基于"ios 时间定时器 NSTimer应用demo",深入探讨`NSTimer`的使用方法、工作原理以及...

    ios-定时器的使用.zip

    在iOS开发中,定时器(Timer)是一种非常重要的工具,它允许我们在特定的时间间隔执行某个任务,例如更新UI、执行动画、实现心跳检测等。在本教程中,我们将深入探讨如何在iOS应用中使用定时器,并通过“火苗”这个...

    ios 多线程编程指南.pdf

    ### iOS多线程编程知识点详解 #### 一、多线程编程概述 多线程编程是一种软件技术,它允许在单个应用程序内并行执行多个代码路径。这有助于提高应用程序的响应性和整体性能,尤其是在利用现代多核处理器的能力时。...

    IOS 多线程

    iOS多线程开发是苹果操作系统上实现多任务并发处理的重要技术,它允许程序在多个线程上同时运行,从而提高应用性能和响应速度。本文将详细介绍iOS多线程开发的关键知识点,包括多线程概念、线程管理、运行循环...

    iOS 多线程编程指南 中文版

    ### iOS多线程编程指南知识点概述 #### 一、多线程编程介绍 - **多线程的概念**:多线程是指在一个程序中同时运行多个线程的能力,这些线程可以独立执行不同的任务或者并行处理同一任务的不同部分。通过多线程,...

    IOS多线程GCD

    通过研究提供的代码示例,开发者可以更直观地了解如何在实际项目中应用GCD,包括任务调度、队列选择、线程间通信等,从而提高iOS应用程序的性能和响应速度。学习和熟练掌握GCD是iOS开发者的必备技能之一。

    ios-定时器.zip

    这个"ios-定时器.zip"文件包含了一个使用UILabel自定义的定时器实现,它能够有效地进行这两种计时方式。下面我们将详细探讨如何利用UILabel来创建一个自定义定时器,并讨论其在实际应用中的使用场景。 首先,...

    iOS多线程技术方案 - Erma_Jack - 博客园1

    在iOS开发中,多线程技术是至关...对于简单的任务,如定时器或后台下载,GCD可能是最好的选择;对于需要更灵活管理和控制的任务,NSOperation可能更适合。理解这些技术并合理运用,可以提升iOS应用的性能和用户体验。

    iOS定时器Demo

    在iOS开发中,定时器(Timer)是一种非常重要的工具,用于在特定的时间间隔后执行某个操作。本Demo主要探讨了iOS中的定时器及其延时功能,通过四个实用的小示例来帮助开发者更好地理解和运用这些技术。以下是每个...

    iOS多线程编程指南(中文版)

    ### iOS多线程编程指南(中文版)知识点详解 #### 一、多线程编程概述 **1.1 什么是多线程** 多线程是指在一个应用程序中同时运行多个线程,每个线程都可以独立执行任务。在iOS开发中,多线程能够充分利用设备的...

Global site tag (gtag.js) - Google Analytics