2014-01-22 2 views
0

У меня есть этот код.Не удается получить доступ к пользовательской информации NSTimer

- (void)scheduleTimerAfterDelay:(NSTimeInterval)delay { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     _timer = [NSTimer scheduledTimerWithTimeInterval:delay 
                target:self 
               selector:@selector(triggerTimer:) 
               userInfo:[NSString stringWithFormat:@"%f", delay] 
               repeats:NO]; 
    }); 
} 

- (void)triggerTimer:(NSTimer *)timer { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSLog(@"Triggered timer after %@ s.", _timer.userInfo); // <-- Exception thrown! 
     // Do stuff 
    }); 
} 

Но когда спусковой таймер, _timer.userInfo вызывает Exception: EXC_BAD_ACCESS (code=1, address=0xc)).

Что я пропустил здесь? Печать _timer в точке останова в строке исключения показывает, что _timer равен <__NSCFTimer: 0x14ec8cb0>. Но я не могу получить доступ к userInfo через lldb. Я использую ARC.

ответ

4

userInfo должен быть словарем:

_timer = [NSTimer scheduledTimerWithTimeInterval:delay 
              target:self 
             selector:@selector(triggerTimer:) 
             userInfo:@{ @"name" : @"Zinedine Zidane", 
                @"age" : @42 } 
             repeats:NO]; 

и вы, очевидно, нужно изменить способ доступа к нему в селекторе:

Вы должны сохранить userInfo перед вызовом dispatch_async():

- (void)triggerTimer:(NSTimer *)timer { 
    NSString *s = timer.userInfo; // Strong reference! 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSLog(@"Triggered timer after %@ s.", s); 
     // Do stuff 
    }); 
} 
+0

В документации указано, что оно должно быть id. https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/occ/instm/NSTimer/userInfo Несмотря на это, его изменение в словарь не изменяет результат. – MdaG

+0

@MdaG Я обновил свой ответ. Вам также потребуется получить доступ к нему в качестве словаря. – trojanfoe

+2

Проблема заключается в том, что таймер запускает «triggerTimer» на mainThread, и вы снова просите отправить на maintherad. Поэтому отправленные работы будут выполняться на следующем runLoop. Но объект таймера действителен только для этой Runloop. – chandu

Смежные вопросы