当前位置:  开发笔记 > IOS > 正文

如何使用performSelector:withObject:afterDelay:在Cocoa中使用原始类型?

如何解决《如何使用performSelector:withObject:afterDelay:在Cocoa中使用原始类型?》经验,为你挑选了7个好方法。

NSObject方法performSelector:withObject:afterDelay:允许我在一定时间后用对象参数调用对象上的方法.它不能用于具有非对象参数的方法(例如,整数,浮点数,结构,非对象指针等).

使用非对象参数的方法实现同样的事情的最简单方法是什么?我知道,对于常规performSelector:withObject:,解决方案是使用NSInvocation(顺便说一句,这真的很复杂).但我不知道如何处理"延迟"部分.

谢谢,



1> 小智..:

以下是我曾经称之为使用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];


对于那些不知道的人来说,我们开始添加参数,因为索引0和1是为隐藏参数"self"和"_cmd"保留的.

2> harms..:

只需在NSNumber中包装float,boolean,int或类似的东西.

对于结构体,我不知道一个方便的解决方案,但你可以创建一个拥有这样一个结构的单独的ObjC类.


NSValue(NSNumber的超类)将包装你给它的任何东西.如果你想包装一个名为'bar'的'struct foo'实例,你会做'[NSValue valueWithBytes:&bar objCType:@encode(struct foo)];'
确认:**必须**为`BOOL`参数传递`nil`以接收`NO`(`FALSE`)
创建一个包装器方法-delayedMethodWithArgument:(NSNumber*)arg.将原语从NSNumber中拉出后,让它调用原始方法.
您可以使用NSValue来包装结构.无论哪种方式,NSNumber/NSValue都是正确的解决方案.

3> 小智..:

不要使用这个答案.我只是为了历史目的而离开了它.请参阅下面的评论.

如果它是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];


**不要使用任何人**.这种方法是严重错误的根源,很难找到.想象一下`self`,地址如`0x0123400`.有了这个approch,你将得到**没有在0.4%**案件中的YES.更糟糕的是,有了这个概率,这个解决方案可能会通过所有测试,并在以后揭示.
@iVishal查看[BOOL的尖角](http://blog.bignerdranch.com/564-bools-sharp-corners/)

4> Remus Rusanu..:

也许NSValue,只是确保你的指针在延迟后仍然有效(即没有在堆栈上分配对象).



5> Michael Gayl..:

我知道这是一个老问题,但如果您正在构建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];     
});



6> Augustine..:

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].



7> justin..:

街区是要走的路.您可以拥有复杂的参数,类型安全,并且它比这里的大多数旧答案更简单,更安全.例如,你可以写:

[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).

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有