2014-01-22 1 views
0

이 코드가 있습니다.NSTimer의 userInfo에 액세스 할 수 없습니다.

- (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.userInfoException: EXC_BAD_ACCESS (code=1, address=0xc))가 발생하는 경우.

여기에 내가 무엇을보고 싶습니까? 예외 줄에 _timer를 인쇄하면 _timer가 <__NSCFTimer: 0x14ec8cb0>임을 알 수 있습니다. 하지만 lldb를 통해 userInfo에 액세스 할 수도 없습니다. ARC를 사용하고 있습니다.

답변

4

userInfo은 사전되어야한다 :

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

당신은 분명히 당신이 선택에 액세스하는 방식으로 변경해야합니다

당신은 dispatch_async()를 호출하기 전에 userInfo을 유지하기 위해 필요를 :

- (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

여기에서 문제는 timer가 mainThread에서 'triggerTimer'를 발생시키고 maintherad에서 파견을 다시 요청한다는 것입니다. 따라서 파견 된 작업은 다음 runLoop에서 수행됩니다. 그러나이 Runloop에서만 타이머 개체가 유효합니다. – chandu