开发者

Using performSelector:withObject:afterDelay: with non-object parameters

I want to invoke setEditing:animated: on a table view with a slight delay. Normally, I'd use performSelector:withObject:afterDelay: but

  1. pSwOaD only accepts one parameter
  2. the second parameter to setEditing:animated: is a primitive BOOL - not an object

In the past I would create a dummy开发者_如何学Python method in my own class, like setTableAnimated and then call [self performSelector:@selector(setTableAnimated) withObject:nil afterDelay:0.1f but that feels kludgy to me.

Is there a better way to do it?


Why not use a dispatch_queue ?

  double delayInSeconds = 2.0;
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
  dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      [tableView setEditing …];
  });


You need to use NSInvocation:

See this code, taken from this answer, and I've changed it slightly to match your question:

BOOL yes = YES;
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self.tableView methodSignatureForSelector:@selector(setEditing:Animated:)]];
[inv setSelector:@selector(setEditing:Animated:)];
[inv setTarget:self.tableView];
[inv setArgument:&yes atIndex:2]; //this is the editing BOOL (0 and 1 are explained in the link above)
[inv setArgument:&yes atIndex:3]; //this is the animated BOOL
[inv performSelector:@selector(invoke) withObject:nil afterDelay:0.1f];


The selector setEditing:animated: is not compatible with performSelector:withObject:afterDelay. You can only call methods with 0 or 1 arguments and the argument (if any) MUST be an object. So your workaround is the way to go. You can wrap the BOOL value in an NSValue object and pass it to your setTableAnimated method.


If you can get your head around it, use an NSInvocation grabber to make an invocation object & call it with a delay with 1 line instead of many: http://overooped.com/post/913725384/nsinvocation

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜