一:operations(任务)
cocoa提供了三种不同的operations
1:Block operations(NSBlockOperation)
These facilitate the execution of one ormore block objects.
#import
@interface OperationsAppDelegate : NSObject {
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 {
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);
}
}];
self.simpleOperation = newBlockOperation;
[self.simpleOperation start];
NSLog(@"Main thread is here");
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[simpleOperation release];
[window release];
[super dealloc];
}
@end
2:Invocationoperations( NSInvocationOperation)
These allow you to invoke a method in another, currently existingobject.
NSNumber *simpleObject = [NSNumber numberWithInteger:123];
NSInvocationOperation *newOperation = [[NSInvocationOperationalloc] initWithTarget:selfselector:@selector(simpleOperationEntry:) object:simpleObject];
[newOperation
调用start方法执行改任务
#import
@interface OperationsAppDelegate : NSObject {
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. Thecode to be executed
will be written inside the main methodof 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
以上三种Operation都可以添加到NSOperationQueue中,添加后立即被执行。
NSOperationQueue 可以设置最大并行执行任务数。默认值为-1无限制。
三:多个任务之间存在依赖关系
设置方式:
[self.firstOperationaddDependency:self.secondOperation];
dependency:附属的意思
把secondOperation做为firstOperation的附属。因此先执行secondOperation,再执行firstOperation。
四:延时执行某个方法
1:performSelector:withObject:afterDelay:
- (void) connectionHasFailedWithError:(NSError *)paramError onRemoteURL:(NSURL *)paramRemoteURL{
[self performSelector:@selector(attemptToDownloadRemoteURL:) withObject:paramRemoteURL afterDelay:3.0f];
}
- (void) attemptToDownloadRemoteURL:(NSURL *)paramRemoteURL{
}
该方法只能接受一个参数。如果需要传递多个参数怎么办呢???
(1)如果调用的selector不接受参数则,withObject:nil
(2) 通过performSelector:withObjcet:afterDelay调用的方法不能有返回值
2:取消延时执行的方法
(1)cancelPreviousPerformReq
(2)
五:NSTimer
1:scheduledTimerWithTimeIn
2:invalidate
调用invalidate方法,不仅是释放NSTimer,还释放userinfo对象。
如果repeats设置为NO,NSTimer在调用完成之后就知道失效,随即释放userinfo对象
3:scheduledTimerWithTimeIn
- (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 scheduledTimerWithTimeInterval:1.0
invocation:invocation
repeats:YES];
self.paintingTimer = newTimer;
}
- (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:
- (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{
NSLog(@"Painting");
}
六:NSThread
1:initWithTarget:selector:object:
2:detachNewThreadSelector:toTarget: withObject:
以上两种方式,selector调用的函数,必须声明自己的NSAutoreleasePool
3:performSelectorInBackgro
[self performSelectorInBackground:@selector(thirdCounter) withObject:nil];
4:start
调用start方法启动线程
5:cancel
调用cancel方法,并把变量赋值为nil
6:cancel vs exit
对于线程调用cancel方法停止,不要调用exit,因为exit方法没有给线程清理自己并释放资源的时间
7:线程的内存泄露
- (void) newThreadEntryPoint{
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self performSelector:@selector(allocateSomething)];
[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];
}
- (void)viewDidLoad {
[NSThread detachNewThreadSelector:@selector(newThreadEntryPoint)
toTarget:self
withObject:nil];
}
UIImage *myImage = [[[UIImage alloc] initWithData:imageData]autorelease];-------------自动释放池的范围
[self performSelector:@selector(allocateSomething)];
调用改方法myImage 对象被添加进该新建线程的自动释放池,但因为在这里没有声明NSAutoreleasePool造成内存泄露
[selfperformSelectorOnMainThr
withObject:nil
调用改方法myImage 对象被放进主线程的自动释放池,在主线程销毁是被自动释放