该NSObject
方法performSelector:withObject:afterDelay:
允许我在一定时间后用对象参数调用对象上的方法.它不能用于具有非对象参数的方法(例如,整数,浮点数,结构,非对象指针等).
使用非对象参数的方法实现同样的事情的最简单方法是什么?我知道,对于常规performSelector:withObject:
,解决方案是使用NSInvocation
(顺便说一句,这真的很复杂).但我不知道如何处理"延迟"部分.
谢谢,
以下是我曾经称之为使用NSInvocation无法更改的内容:
SEL theSelector = NSSelectorFromString(@"setOrientation:animated:"); NSInvocation *anInvocation = [NSInvocation invocationWithMethodSignature: [MPMoviePlayerController instanceMethodSignatureForSelector:theSelector]]; [anInvocation setSelector:theSelector]; [anInvocation setTarget:theMovie]; UIInterfaceOrientation val = UIInterfaceOrientationPortrait; BOOL anim = NO; [anInvocation setArgument:&val atIndex:2]; [anInvocation setArgument:&anim atIndex:3]; [anInvocation performSelector:@selector(invoke) withObject:nil afterDelay:1];
只需在NSNumber中包装float,boolean,int或类似的东西.
对于结构体,我不知道一个方便的解决方案,但你可以创建一个拥有这样一个结构的单独的ObjC类.
不要使用这个答案.我只是为了历史目的而离开了它.请参阅下面的评论.
如果它是BOOL参数,有一个简单的技巧.
通过NO为NO和self为YES.nil被转换为NO的BOOL值.self被转换为BOOL值为YES.
如果它不是BOOL参数,则该方法会中断.
假设自我是一个UIView.
//nil will be cast to NO when the selector is performed [self performSelector:@selector(setHidden:) withObject:nil afterDelay:5.0]; //self will be cast to YES when the selector is performed [self performSelector:@selector(setHidden:) withObject:self afterDelay:10.0];
也许NSValue,只是确保你的指针在延迟后仍然有效(即没有在堆栈上分配对象).
我知道这是一个老问题,但如果您正在构建iOS SDK 4+,那么您可以使用块来轻松完成此操作并使其更具可读性:
double delayInSeconds = 2.0; int primitiveValue = 500; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self doSomethingWithPrimitive:primitiveValue]; });
PerformSelector:WithObject总是接受一个对象,所以为了传递像int/double/float等参数.....你可以使用这样的东西.
//NSNumber is an object.. [self performSelector:@selector(setUserAlphaNumber:) withObject: [NSNumber numberWithFloat: 1.0f] afterDelay:1.5]; -(void) setUserAlphaNumber: (NSNumber*) number{ [txtUsername setAlpha: [number floatValue] ]; }
同样的方法你可以使用[NSNumber numberWithInt:]等....在接收方法中你可以将数字转换为格式为[number int]或[number double].
街区是要走的路.您可以拥有复杂的参数,类型安全,并且它比这里的大多数旧答案更简单,更安全.例如,你可以写:
[MONBlock performBlock:^{[obj setFrame:SOMETHING];} afterDelay:2];
块允许您捕获任意参数列表,引用对象和变量.
支持实施(基础):
@interface MONBlock : NSObject + (void)performBlock:(void(^)())pBlock afterDelay:(NSTimeInterval)pDelay; @end @implementation MONBlock + (void)imp_performBlock:(void(^)())pBlock { pBlock(); } + (void)performBlock:(void(^)())pBlock afterDelay:(NSTimeInterval)pDelay { [self performSelector:@selector(imp_performBlock:) withObject:[pBlock copy] afterDelay:pDelay]; } @end
例:
int main(int argc, const char * argv[]) { @autoreleasepool { __block bool didPrint = false; int pi = 3; // close enough =p [MONBlock performBlock:^{NSLog(@"Hello, World! pi is %i", pi); didPrint = true;} afterDelay:2]; while (!didPrint) { [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeInterval:0.1 sinceDate:NSDate.date]]; } NSLog(@"(Bye, World!)"); } return 0; }
另请参阅Michael的答案(+1).