Iphone IOS-性能选择器:withObject:afterDelay:不工作

Iphone IOS-性能选择器:withObject:afterDelay:不工作,iphone,ios,objective-c,Iphone,Ios,Objective C,参考资料: 就像上面的链接说的,但它似乎没有解释原因 在我的代码中,以下内容将起作用: dispatch_async(dispatch_get_main_queue(), ^{ [self performSelector: @selector(helloWorld) withObject:nil afterDelay:0.5]; }); 但是,当我评论这样的东西时,(我真的确定我在主线程中运行它!!),代码不起作用: // dispatch_async(dispatc

参考资料:

就像上面的链接说的,但它似乎没有解释原因

在我的代码中,以下内容将起作用:

dispatch_async(dispatch_get_main_queue(), ^{
       [self performSelector:  @selector(helloWorld) withObject:nil afterDelay:0.5];
}); 
但是,当我评论这样的东西时,(我真的确定我在主线程中运行它!!),代码不起作用:

//    dispatch_async(dispatch_get_main_queue(), ^{
        [self performSelector:  @selector(helloWorld) withObject:nil afterDelay: 0.5];
//    });
谁能告诉我为什么“自我”将不再发布/取消分配,我保留它直到应用程序结束

“不工作”,意味着,(无崩溃)它不会跳转到“helloWorld”方法:

我认为是运行循环导致了这个问题。如前所述,但我需要更多细节或更明确的解释。

编辑 如评论中所述,performSelector:withObject:afterDelay:也会保留您的对象,因此忽略我的答案。 结束编辑

我知道你在用ARC。你的街区正在保留你的物体

dispatch_async(dispatch_get_main_queue(), ^{
       [self performSelector:  @selector(helloWorld) withObject:nil afterDelay:aTimeUnit];
});
这就是选择器被触发的原因。注释块时,没有人保留对对象的引用,因此它会自动释放

//    dispatch_async(dispatch_get_main_queue(), ^{
        [self performSelector:  @selector(helloWorld) withObject:nil afterDelay: aTimeUnit];
//    });
aTimeUnit
过去时,self可能已被释放,因此选择器调用丢失。那是你的问题

应该避免在块内捕获self,因为如果将块存储在ivar中,可能会导致保留循环,从而导致对象无法释放。他们在这里谈到:

当我遇到这种情况时,我正在从GCD调度呼叫performSelector。因此,它在GCD工作线程中设置计时器,该线程在计时器启动之前就消失了。当GCD删除工作线程时,计时器丢失,因此从未调用选择器。

表示:

请注意: 它仅在默认模式下成功(NSDefaultRunLoopMode)

现在。假设您有如下代码:

dispatch_async(dispatch_queue_create("com.serial.thread", DISPATCH_QUEUE_SERIAL), ^{
    NSLog(@"1");
    [self performSelector:@selector(testLog2) withObject:nil afterDelay:0];
});
PO
线程中的
[nsrunlop currentlunloop]

<CFRunLoop 0x6040001ea000 [0x10c642960]>
{
 wakeup port   = 0x5207, 
 stopped       = false, 
 ignoreWakeUps = true, 
 current mode  = (none),.....
}
<CFRunLoop 0x6000001e9700 [0x10c642960]>
{
 wakeup port   = 0x1d03, 
 stopped       = false, 
 ignoreWakeUps = false, 
 current mode  = kCFRunLoopDefaultMode,......
}

@isaacselement

如果您确实在主线程上,那么这就很奇怪了。您为什么不使用
dispatch\u after()
?什么是BROKER.actors.event?在第一个代码中,您使用的是
self
,而在第二个代码中,您使用的是
BROKER.actors.event
。那么你确定他们指的是同一件事吗?“不起作用”。。。意思它会崩溃吗?在这种情况下,日志消息是什么?看到您上次的编辑,看起来您不在主线程上,在这种情况下@WaltSellers的答案适用。你到底是如何测试你是否在主线程上的?你能写一个小测试用例来重现你的问题吗?对一个释放对象的选择器调用通常会以崩溃结束,对吗?我很确定performSelector也会保留所有内容。作为w.sellers,我也认为performSelector会成为感兴趣对象的所有者,保留它直到它执行选择器,因此,在这段时间里,没有必要担心自己会被解约
<CFRunLoop 0x6040001ea000 [0x10c642960]>
{
 wakeup port   = 0x5207, 
 stopped       = false, 
 ignoreWakeUps = true, 
 current mode  = (none),.....
}
<CFRunLoop 0x6000001e9700 [0x10c642960]>
{
 wakeup port   = 0x1d03, 
 stopped       = false, 
 ignoreWakeUps = false, 
 current mode  = kCFRunLoopDefaultMode,......
}