iOS [NSTimer scheduledTimerWith

2018-04-10  本文已影响30人  SmallWhiteMouse

第一步:配置NSInvocation

- (id)performSelector:(SEL)aSelector withArgument:(id)anArgument{
    
    if (aSelector == nil) return nil;
    NSMethodSignature   *signature = [[self class] instanceMethodSignatureForSelector:aSelector];
    NSInvocation  *invocation = [NSInvocation  invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = aSelector;
    
    //NSInvocation 有两个隐藏参数,所以anArgument
    if ([anArgument isKindOfClass:[NSArray class]]) {
        
        NSInteger  count = MIN(signature.numberOfArguments-2, [(NSArray *)anArgument count]);
        
        for (int i = 0; i< count; i++) {
            
            const char *type  = [signature getArgumentTypeAtIndex:i + 2];
            
            //需要做参数类型判断然后解析成对应类型,这里默认所有参数都是OC对象
            if (strcmp(type, "@") == 0) {
                id argument = anArgument[i];
                [invocation setArgument:&argument atIndex:2+i];
            }
        }
        
    }
    
    [invocation invoke];
    return invocation;
}

第二步 :创建NSTimer需要调用的方法

- (void) run:(NSString *)run drink:(NSArray *)drink  sleep:(NSDictionary *)sellp{
    
    NSLog(@"run------%@",run);
    NSLog(@"drink------%@",drink);
    NSLog(@"sleep------%@",sellp);
}

第三步:使用NSTimer

 [NSTimer scheduledTimerWithTimeInterval:1.0
                                 invocation:[self performSelector:@selector(run:drink:sleep:) withArgument:@[@{@"key":@"sellp"},@"run",@[self.view,@"1"]]]
                                    repeats:YES];

特别提醒 :

1、临时变量抽取

EXC_BAD_ACCESS.png

这样写导致报错EXC_BAD_ACCESS。

原因:

[NSTimer scheduled....]
NSTimer 调用这个方法系统会自动将这个临时对象保持住,即retainCount 系统帮你加1;但是成员变量,invocation 是自己创建的临时对象,用一次就释放掉了,等下一次runloop进入的时候NSInvocation 对象被释放,所以奔溃。

所以还是用第三部中的方法就可以了

2、NSTimer保险使用

 [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

可能出现的问题:如果默认加载主线程的话,人为操作UI或者代码为主线程添加操作,导致主线程优先处理UI事件。NSTimer就被阻塞。

如果您有什么疑问或者书写歧义,非常感激您能留言~

上一篇下一篇

猜你喜欢

热点阅读