使用NSOperation使用,创建线程中传递多个参数

参考:http://blog.csdn.net/dqjyong/article/details/7677557

参考:http://stackoverflow.com/questions/2327617/calling-selector-with-two-arguments-on-nsthread-issue

使用NSInvocation对象

NSInvocation* deleteInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(deleteDataAtPath:)]];
          [deleteInvocation setTarget:self];
          [deleteInvocation setSelector:@selector(deleteDataAtPath:)];//给NSInvocation对象添加对应的动作
    // // self, _cmd, ... 参数索引必须是2以后
          [deleteInvocation setArgument:&cachePath atIndex:2];
         //用NSInvocation对象来初始化一个NSOperation的子类NSInvocationOperation对象
          NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invoction];

         //初始化一个操作队列
          NSOperationQueue* operationQueue=[[NSOperationQueue alloc] init];

         //在操作队列中加入操作
          [operationQueue addOperation:operation];
          [operation release];        

具体实现:

NSThread+ManyObjects.h:

@interface NSThread (ManyObjects)

+ (void)detachNewThreadSelector:(SEL)aSelector
                       toTarget:(id)aTarget 
                     withObject:(id)anArgument
                      andObject:(id)anotherArgument;

@end

NSThread+ManyObjects.m:

@implementation NSThread (ManyObjects)

+ (void)detachNewThreadSelector:(SEL)aSelector
                       toTarget:(id)aTarget 
                     withObject:(id)anArgument
                      andObject:(id)anotherArgument
{
    NSMethodSignature *signature = [aTarget methodSignatureForSelector:aSelector];
    if (!signature) return;

    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:aTarget];
    [invocation setSelector:aSelector];
    [invocation setArgument:&anArgument atIndex:2];
    [invocation setArgument:&anotherArgument atIndex:3];
    [invocation retainArguments];

    [self detachNewThreadSelector:@selector(invoke) toTarget:invocation withObject:nil];
}

@end

调用:

[NSThread detachNewThreadSelector:@selector(loginWithUser:user:password:) toTarget:self withObject:@"someusername" andObject:@"somepassword"];

另一种实现:

参考:http://blog.engledew.com/post/730804661/nsthread-a-selector-with-multiple-arguments

#import <Foundation/Foundation.h>
 
@interface SEThreadInvocation : NSObject
{
    NSThread * _thread;
    NSInvocation * _invocation;
}
 
@property(nonatomic,retain) NSThread * thread;
@property(nonatomic,retain) NSInvocation * invocation;
 
- (id) initWithTarget:(id)target selector:(SEL)selector arguments:(NSArray *)arguments;
+ (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObjects:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;
- (void) start;
 
@end
#import "SEThreadInvocation.h"
 
@implementation SEThreadInvocation
 
@synthesize thread = _thread;
@synthesize invocation = _invocation;
 
- (id) initWithTarget:(id)target selector:(SEL)selector arguments:(NSArray *)arguments
{
    if (self = [super init])
    {
        _thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        _thread.name = @"SEThreadInvocation";
 
        NSMethodSignature * signature = [target methodSignatureForSelector:selector];
 
        self.invocation = [NSInvocation invocationWithMethodSignature:signature];
 
        [_invocation setTarget:target];
        [_invocation setSelector:selector];
 
        NSInteger i = 2; // self, _cmd, ...
        
        for (id argument in arguments)
        {
            [_invocation setArgument:&argument atIndex:i++];
        }
        
        [_invocation retainArguments];
    }
    return self;
}
 
- (void)start
{
    [_thread start];
}
 
- (void)run
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    [_invocation invoke];
 
    [pool release];
}
 
 
+ (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObjects:(id)firstObject, ...
{
    NSMutableArray * arguments = [NSMutableArray array];
    
    if (firstObject)
    {
        [arguments addObject:firstObject];
        
        id argument;
        va_list objectList;
        va_start(objectList, firstObject);
 
        while (argument = va_arg(objectList, id))
        {
            [arguments addObject:argument];
        }
        
        va_end(objectList);
    }
 
    SEThreadInvocation * threadInvocation = [[SEThreadInvocation alloc] initWithTarget:target selector:selector arguments:arguments];
    [threadInvocation start];
    [threadInvocation autorelease];
}
 
- (void) dealloc
{
    [_invocation release];
    [_thread release];
 
    [super dealloc];
}
 
@end
[SEThreadInvocation detachNewThreadSelector:@selector(request:processData:)
                                   toTarget:self
                                withObjects:request, data, nil];
原文地址:https://www.cnblogs.com/programmer-blog/p/3271824.html