通过块在我的情况的参数

问题描述:

我有一个函数,它接受一个作为参数:通过块在我的情况的参数

typedef void (^ MyBlock)(int); 

-(void)doTask:(MyBlock)theBlock{ 
... 
} 

我需要上述功能在另一个线程运行,我想用- performSelector:onThread:withObject:waitUntilDone:,我当前的代码:

NSThread *workerThread = [[NSThread alloc] init]; 
[workerThread start]; 

[self performSelector:@selector(doTask:) 
      onThread:workerThread 
      withObject:??? 
     waitUntilDone:NO]; 

但是,如何通过MyBlock参数与这种方法? (请不要建议GCD,我想知道我该怎么做我当前的代码,这可能吗?)

+0

http://goshdarnblocksyntax.com/ – Kreiri

+0

@Kreiri,你看过我的问题吗?链接与我的问题无关。 –

+0

你读过那里的第一行吗? – Kreiri

[self performSelector:@selector(someMethod) 
     onThread:[Your thread] 
     withObject:[your object] 
    waitUntilDone:NO]; 

-(void)someMethod 
{ 
    [self doTask:^(int intValue) { 
     // Do your task 
    }]; 
} 
+0

谢谢。其实,我的情况是这样的,你可以请看看http://*.com/questions/38931737/initialize-start-nsthread-with-target-selector –

这个答案假定您正在使用ARC。如果你不是,那么你需要多做一点,但总的来说答案是一样的。

但是,如何通过MyBlock参数与这种方法?

块是一个对象,你不需要做任何特殊的事情。例如:

[self performSelector:@selector(doTask:) 
      onThread:workerThread 
      withObject:^(int arg){ NSLog(@"block passed: %d", arg); } 
     waitUntilDone:NO]; 

HTH

+0

小心:一旦你离开范围它被声明,如果你将块存储在某个地方或者在不同的线程中执行它,会发生这种情况。为了避免麻烦,您需要传递[MyBlock副本]。例如dispatch_async()会为你做这件事。这也是块属性应该“复制”的原因。我怀疑performSelector会自动执行此操作。 – gnasher729

+1

@ gnasher729 - 你发现了开始笔记的原因。块属性需要“复制”已经很长时间了 - *如果使用ARC *。上面的例子工作正常,编译器做一个编译器应该做的事 - 隐藏堆栈优化,并在需要时将块正确地移动到堆中。 – CRD

首先创建线程这样使得它是活的,你可以调用方法从该线程

-(void) myThreadMainMethod: (id) sender { 

    @autoreleasepool { 
     NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 
     [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 

     while (true) { // add your condition for keeping the thread alive 
      [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
     } 
    } 
} 

    NSThread* workerThread = [[NSThread alloc] initWithTarget:self 
               selector:@selector(myThreadMainMethod:) 
                object:nil]; 

    [workerThread start]; 

然后写这样的事情

-(void)doTask:(MyBlock)theBlock{ 
     NSLog(@"do task called now execute the block"); 
     theBlock(1); 
    } 

    MyBlock block1 = ^(int a) { 
     NSLog(@"integer %i", a); 
    }; 

    [self performSelector:@selector(doTask:) 
       onThread:[NSThread mainThread] 
       withObject:block1 
      waitUntilDone:NO];