use*_*008 96 cocoa objective-c
该NSObject方法performSelector:withObject:afterDelay:允许我在一定时间后用对象参数调用对象上的方法.它不能用于具有非对象参数的方法(例如,整数,浮点数,结构,非对象指针等).
使用非对象参数的方法实现同样的事情的最简单方法是什么?我知道,对于常规performSelector:withObject:,解决方案是使用NSInvocation(顺便说一句,这真的很复杂).但我不知道如何处理"延迟"部分.
谢谢,
小智 70
以下是我曾经称之为使用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];
Run Code Online (Sandbox Code Playgroud)
har*_*rms 35
只需在NSNumber中包装float,boolean,int或类似的东西.
对于结构体,我不知道一个方便的解决方案,但你可以创建一个拥有这样一个结构的单独的ObjC类.
小智 13
不要使用这个答案.我只是为了历史目的而离开了它.请参阅下面的评论.
如果它是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];
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但如果您正在构建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];
});
Run Code Online (Sandbox Code Playgroud)
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] ];
}
Run Code Online (Sandbox Code Playgroud)
同样的方法你可以使用[NSNumber numberWithInt:]等....在接收方法中你可以将数字转换为格式为[number int]或[number double].
街区是要走的路.您可以拥有复杂的参数,类型安全,并且它比这里的大多数旧答案更简单,更安全.例如,你可以写:
[MONBlock performBlock:^{[obj setFrame:SOMETHING];} afterDelay:2];
Run Code Online (Sandbox Code Playgroud)
块允许您捕获任意参数列表,引用对象和变量.
支持实施(基础):
@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
Run Code Online (Sandbox Code Playgroud)
例:
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;
}
Run Code Online (Sandbox Code Playgroud)
另请参阅Michael的答案(+1).
| 归档时间: |
|
| 查看次数: |
139859 次 |
| 最近记录: |