2011-10-01 2 views
1

텍스트 필드의 값을 현재 시간으로 업데이트하는 다음 코드가 있습니다. 내 질문은 : 왜 코드의 하단 부분에 보낸 사람으로 nil을 보냅니 까? CurrentTimeViewController.m(id) sender = nil?

- (IBAction)showCurrentTime:(id)sender 
{ 
NSDate *now = [NSDate date]; 

static NSDateFormatter *formatter = nil; 

if(!formatter) { 
    formatter = [[NSDateFormatter alloc] init]; 
    [formatter setTimeStyle:NSDateFormatterShortStyle]; 
} 

[timeLabel setText:[formatter stringFromDate:now]]; 

} 

[self showCurrentTime:nil];

...

- (void)viewWillAppear:(BOOL)animated 
{ 
    NSLog(@"CurrentTimeViewController will appear"); 
    [super viewWillAppear:animated]; 
    [self showCurrentTime:nil]; 
} 

답변

3

정상적으로 동작 핸들러가 호출되면 때문에 그들은 UIButton 같은 방법으로 통화를 개시 오브젝트를 전달할 또는 UISegmentedControl 그러나 액션의 결과가 아닌 코드에서 메서드를 호출하려는 경우에는 인간을 sender으로 전달할 수 없으므로 nil을 전달합니다. 또한

- (IBAction)은이 방법에 Touch Up Inside 드래그하여 Interface Builder 통해 이벤트에 접속 (또는 외부/등 터치 다운) (이벤트의 일종을 가지고 또는 다른 제어) 버튼에서 이벤트가 될 수 있음을 나타낸다 을 선택하고 thumbTapped:을 선택하십시오. 그것은 때문에 년대 sender

- (IBAction)thumbTapped:(id)sender { 
    if ([sender isKindOfClass:[UIButton class]] && ((UIButton *)sender).tag == 1001) { 
     iPhoneImagePreviewViewController *previewVC = [[iPhoneImagePreviewViewController alloc] initWithNibName:@"iPhoneImagePreviewViewController" bundle:nil]; 
     [self.navigationController pushViewController:previewVC animated:YES]; 
     [previewVC release]; 
    } else { 
     [[[[UIAlertView alloc] initWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] 
            message:@"This method was called from somewhere in user code, not as the result of an action!" 
            delegate:self 
          cancelButtonTitle:@"OK" 
          otherButtonTitles:nil] autorelease] show]; 
    } 
} 
1

button 객체를 전달 thumbTapped:를 호출,

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
button.tag = 1001; 
[button addTarget:self action:@selector(thumbTapped:) forControlEvents:UIControlEventTouchUpInside]; 

터치가 해제됩니다 (터치 버튼 내부에 여전히) : 예를 들어

으로 보내야합니다. 호출하는 메소드의 서명에 인수가 필요하기 때문입니다.

:(id)sender은 일반적으로 버튼 누르기 동작에서 볼 수 있습니다. nib의 버튼을 View Controller의 메소드에 연결하면, 인수를 취할 수 있는지 확인합니다. 이 경우 '발신자'는 펜촉에서 생성 된 UIButton의 인스턴스를 가리 킵니다.

프로그래밍 방식의 버튼 만들기 및 셀렉터를 보내는 많은 경우에도 마찬가지입니다.

1

showCurrentTime 함수에 대한 지정에는 sender라는 1 개의 인수가 있습니다. 객체의 ID를 보내지 않고 함수를 호출하면 호출은 유효하지 않습니다.

목표 -c에서 NULL 대신 Nil이 사용되며 호출하는 함수의 스펙을 충족시키기 위해 순수하게 전송됩니다.

함수는 실제로 본문 내의 인수를 사용하지 않으므로 함수에 보낼 개체는 실제로 중요하지 않습니다.

3

가장 일반적인 형식의 IBAction 메서드는 단일 보낸 사람 인수를 사용합니다. 시스템에 의해 호출되면 액션을 트리거 한 컨트롤을 보낸 사람 매개 변수로 전달합니다. 메소드를 직접 호출하려면 발신자를 제공해야합니다. 이 메소드는 방금 사용자와 상호 작용 한 컨트롤에 의해 호출되지 않으므로 nil이 사용됩니다.

실제로 행동을 직접 호출하는 것은 좋은 패턴이 아니라고 생각합니다.IBAction 태그가있는 메서드를 사용하면 "이 메서드는 사용자 작업에 대한 응답으로 호출됩니다"라는 의미이며 해당 메서드 내에서 작업 할 때 의존 할 수있는 중요한 컨텍스트 비트입니다. 코드가 메서드를 직접 호출하면 아이디어가 위반 된 것입니다.

- (void)updateTime:(NSDate *)date { 
    static NSDateFormatter *formatter = nil; 
    if(!formatter) { 
     formatter = [[NSDateFormatter alloc] init]; 
     [formatter setTimeStyle:NSDateFormatterShortStyle]; 
    } 

    [timeLabel setText:[formatter stringFromDate:date]]; 
} 

- (IBAction)showCurrentTime:(id)sender { 
    [self updateTime:[NSDate date]]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [self updateTime:[NSDate date]]; 
} 
:

보통 나는 이런 식으로 뭔가를 할 더 나은 것 같아요