(id) отправитель = ноль? - PullRequest
       3

(id) отправитель = ноль?

1 голос
/ 02 октября 2011

У меня есть следующий код, который обновляет значение текстового поля с текущим временем. Мой вопрос: почему вы отправляете nil в качестве отправителя в нижней части кода? [self showCurrentTime:nil];

CurrentTimeViewController.m

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

}

...

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

Ответы [ 4 ]

3 голосов
/ 02 октября 2011

Методы 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]];
}
3 голосов
/ 02 октября 2011

Потому что обычно, когда вызываются обработчики действий, они передают объект, который инициировал вызов, методу, например UIButton или UISegmentedControl. Но когда вы хотите вызвать метод из своего кода, а не как результат действия, вы не можете передать человека как sender, поэтому вы передаете nil.

Кроме того, - (IBAction) указывает, что этот метод может быть связан с событием через Interface Builder путем перетаскивания события Touch Up Inside (или касания снаружи / и т. Д.) Из кнопки (или любого другого элемента управления, который имеет некоторые сортировать события) до File's Owner и выбрать thumbTapped:.

Например:

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

Когда касание отпущено (и касание все еще находится внутри кнопки), вызовет thumbTapped:, передав объект button как 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 голос
/ 02 октября 2011

Спецификация для функции showCurrentTime имеет 1 аргумент с именем sender. Если вы вызвали функцию без отправки идентификатора объекта, вызов будет недействительным.

В target-c вместо NULL используется ноль, и он просто отправляется для удовлетворения спецификации вызываемой вами функции.

Поскольку функция фактически не использует аргумент в теле, на самом деле не имеет значения, какой объект вы отправляете в функцию.

1 голос
/ 02 октября 2011

Это потому, что вам нужно отправить что-то , поскольку сигнатура вызываемого вами метода принимает аргумент.

:(id)sender обычно наблюдается в действиях при нажатии кнопки.Когда вы подключаете кнопку в кончике к методу в вашем контроллере представления, он проверит, может ли он принять аргумент.Если это так, «отправитель» будет указывать на экземпляр UIButton, который был создан в перо.

Это также верно для создания программных кнопок и многих других случаях, когда вы отправляете селекторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...