在新线程(iphone)中调用方法时传递变量

时间:2011-01-13 09:29:01

标签: iphone objective-c multithreading

我需要在创建新线程时将变量传递给线程方法

我的代码是以下 //生成线程

  

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

线程工作

- (void)startThread:(NSInteger *)var img:(UIImageView *) Img{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [NSThread sleepForTimeInterval:var];
    [self performSelectorOnMainThread:@selector(threadMethod) withObject:nil waitUntilDone:NO];

//我需要将Img传递给threadMethod:         [池发布];     } 线程方法

 - (void)threadMethod:(UIImageView *) Img {
        //do some coding.
    }

所以我怎么做(将参数传递给两个方法

3 个答案:

答案 0 :(得分:1)

我看到你提供的代码只是使用线程来实现延迟。您可以轻松地执行此操作,而无需引入这样的线程:

[myImageView performSelector:@selector(setImage:)
                  withObject:image
                  afterDelay:5.0];

对于更复杂的需求,我在NSInvocation上编写了一个类别,允许您在任何线程上轻松调用任何独立于参数的方法。

例如,我有这个方法:

-(void)doStuffWithImage:(UIImage*)image callbackAfterDelay:(NSTimeInterval)to {
  NSAutoreleasePool* pool = [[UIAutoreleasePool alloc] init];
  // ... do stuff
  [NSThread sleepForTimeInterval:ti];
  [self performSelectorOnMainThread:@selector(callbackWithImage:)
                         withObject:image
                      waitUntilDone:NO];
  [pool release];
}

这很容易,但在辅助线程上生成此方法并不容易。我的类别允许您使用这个简单的代码来完成:

[[NSInvocation invocationWithTarget:self
                           selector:@selector(doStuffWithImage:callbackAfterDelay:)
                    retainArguments:YES, image, 5.0] invokeInBackground];

在这里您可以找到代码和博客文章,详细说明实现的原因和方式: http://blog.jayway.com/2010/03/30/performing-any-selector-on-the-main-thread/

答案 1 :(得分:0)

我有理由相信UIImage不是线程安全的,所以你可能会在那里运气不好。一般来说,其中任何一个:

  • 使对象成为实例变量
  • 使对象成为全局
  • 捕获块中的变量并使用dispatch_async来执行线程工作而不是NSThread
  • 使用NSConnection

    将对象发送到线程

    等...

请记住,仅仅因为您对该对象的引用并不意味着它的使用是安全的。考虑线程安全保证(主线程仅针对一个线程而不针对一个编写器而不是线程安全),并考虑在何处需要使用锁或队列来保护线程之间共享的资源。

答案 2 :(得分:0)

您只能使用withObject:传递一个参数,更改代码如下

[self performSelectorOnMainThread:@selector(threadMethod) 
                       withObject:image 
                    waitUntilDone:NO];

如果您需要传递多个值,请将其作为数组,然后传递它。

UIComponents不是线程安全的,所以在将UI组件传递给线程时要小心。