самостоятельно IBAction и отправитель

Я начинающий программист iOS, вот мой вопрос: у меня есть представление карты и сегментированное управление, а также функция changeMapType, которая вызывается, когда происходит UIControlEventValueChanged, например

// change map type with segmented control
- (IBAction)changeMapType:(id)sender
{
    NSInteger i = [mapTypeControl selectedSegmentIndex];
    if (i == 0){
        [worldView setMapType:MKMapTypeStandard];
    }
    if (i == 1) {
        [worldView setMapType:MKMapTypeSatellite];
    }
    if (i == 2) {
        [worldView setMapType:MKMapTypeHybrid];
    }
}

и в viewDidLoad я хочу вызвать этот метод, чтобы установить, какой тип карты будет первым.

[mapTypeControl setSelectedSegmentIndex:2];
[self changeMapType:nil];

код выше работает нормально, но код ниже тоже работает нормально

[mapTypeControl setSelectedSegmentIndex:2];
[self changeMapType:self];

Итак, наконец, что передать как SENDER? что правильно?


person smoke    schedule 08.03.2013    source источник


Ответы (5)


Поскольку вы на самом деле ничего не делаете с "sender" (передается в ваш метод IBAction), вы можете передать практически все, что захотите.

Используйте «self» или «nil», и все будет в порядке.

Если вы делаете в конечном итоге используете "sender" в любом из ваших действий IBAction, вам нужно позаботиться о том, что вы отправляете программно. Когда вы нажимаете кнопку или какой-либо объект в пользовательском интерфейсе, связанный с вашим действием, отправляется ссылка на этот объект.

p.s. это похоже на вечеринку ответов здесь!

person Michael Dautermann    schedule 08.03.2013

Концептуально ни один из них не является правильным, на практике оба хороши.

sender является (или, по крайней мере, должен быть) экземпляром UIControl (сегментированный элемент управления в вашем случае), который инициирует действие. Фактически, вы должны начать свой метод так:

- (IBAction)changeMapType:(UISegmentedControl *)sender
{
    NSInteger i = [sender selectedSegmentIndex];

    // etc.
}

И при вызове вручную вы должны передать сегментированный элемент управления:

[self changeMapType:mapTypeControl];
person Community    schedule 08.03.2013
comment
как насчет того, чтобы xcode предоставил нам (id) отправителя? Вы предлагаете изменить для всех действий? Anywaz понравилась твоя фотка по сравнению с пингвинами :) - person Anoop Vaidya; 08.03.2013
comment
@AnoopVaidya IDK, почему по умолчанию используется id, в этих случаях это всегда экземпляр UIControl. Xcode - дерьмо. - person ; 08.03.2013
comment
в osx иногда это NSComboBox, NSButton и т. д., поэтому я предполагаю, что они хотели сделать его универсальным. Не так ли, и после получения (id) отправителя мы конвертируем: UIButton *button=(UIButton *)sender - person Anoop Vaidya; 08.03.2013
comment
@AnoopVaidya Здесь мы говорим об iOS. - person ; 08.03.2013
comment
да, в документации сказано, что это должен быть (id) отправитель, я думаю, чтобы охватить все случаи. - person smoke; 08.03.2013

любой из них в порядке, так как вы даже не используете sender в своем методе... обычно он там, если методу нужно что-то знать о том, какой объект использовал функцию, чтобы вы могли пойти if([sender isKindOfClass:[SomeObject class]])

person Fonix    schedule 08.03.2013

Для IBAction отправителем является интерфейсный объект, отправивший вызов сообщения. В вашем случае, запускающем это программно, такого объекта нет, поэтому вы должны передать nil.

person Purpletoucan    schedule 08.03.2013

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

На самом деле, я бы посоветовал вам изменить метод, чтобы вообще не принимать параметр sender.

- (IBAction)changeMapType

Действия управления могут иметь 3 возможных подписи:

- (IBAction)changeMapType
- (IBAction)changeMapType:(id)sender
- (IBAction)changeMapType:(id)sender forEvent:(UIEvent *)event

Дополнительные параметры лучше брать только в том случае, если вы их используете.

И как только вы избавитесь от этого параметра, вам не придется беспокоиться о том, что ему передать. И это решение на самом деле правильное — вы не передаете что-то, что на самом деле не является отправителем.

Если вы передаете что-то случайное, например nil, вы можете в один прекрасный день решить использовать параметр sender и забыть, что вы передали мусор в одном месте, что вызвало проблемы. Однако, если вы удалили параметр вообще, то при необходимости использовать параметр sender вам нужно будет изменить имя метода, что предполагает изменение всех мест, где он вызывается (иначе он не скомпилируется, так как имя метода измененный). Так что случайно не накосячишь.

person newacct    schedule 09.03.2013