iOS 多线程详解
来源:互联网 发布:js 字符串等于 编辑:程序博客网 时间:2024/05/22 03:46
一: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 对象被放进主线程的自动释放池,在主线程销毁是被自动释放
- ios多线程---GCD详解
- iOS 多线程详解
- ios多线程开发详解
- iOS 多线程详解
- 详解iOS多线程
- IOS多线程开发详解
- iOS多线程GCD详解
- iOS 开发 多线程详解
- iOS-多线程详解
- iOS-多线程详解
- iOS多线程详解
- IOS多线程技术详解
- iOS开发多线程详解
- iOS多线程安全详解
- ios多线程详解
- iOS多线程之GCD详解
- 【IOS多线程】之GCD详解
- IOS多线程编程步骤详解
- linux 修改IP, DNS 命令
- PyQt按钮右键菜单
- CAS—登录后返回更多用户信息
- C++中的friend友元函数详细解析
- cocos2d-X 卡牌手机游戏《刀塔传奇》完整源码下载
- iOS 多线程详解
- Android数据库更新并保留原来数据的实现
- poj1258
- 黑马程序员--结构体知识总结
- 找内存泄露入的坑
- easyui-datagrid出现乱码问题
- string与wstring转换
- 聊聊map和vector的迭代器失效问题(某公司招聘笔试试题)
- Reveal的使用