2014-01-31 3 views
0

Я построил UIViewController, который реализует различные функции пользовательского интерфейса. Он предназначен для пользователя для подкласса, чтобы он мог обновить его несколькими способами, такими как setContents: и getContents.Методы вызова подкласса UIViewController

В моем UIViewController Я вызываю метод, когда они нажимают кнопку, которую я хочу, чтобы пользователь реализовал в своем подклассе showPicker.

Я хотел бы, чтобы пользователь имел возможность быть в состоянии контролировать то, что они делают в этом методе, поэтому я решил, что они должны просто реализовать в своем подклассе:

- (void)showPicker { 
    // Do what you want 
} 

Для того, чтобы сделать это, Мне пришлось добавить пустой метод с тем же именем в моем исходном UIViewController, а затем добавить его в файл заголовка.

То, что я хочу сделать, точно так же, как вы можете подкласса UIViewController, а затем реализовать viewWillAppear: и делать то, что вы хотите в этом методе.

Правильно ли это, если я хочу, чтобы пользователь мог контролировать, что происходит, когда кнопка внутри моего класса используется? Я делаю все это неправильно? Должен ли я использовать делегатов?

ответ

1

Если вы хотите эмулировать, что делает UIViewController с viewWillAppear:, вам нужно будет добавить ничегонеделания реализацию showPicker в своем базовом классе. UIViewController.h указывает, что viewWillAppear: имеет реализацию по умолчанию, которая ничего не делает.

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

Других вариантов здесь, чтобы сделать что-то вдоль линий:

if ([self canPerformSelector:@selector(showPicker)]) { 
    ... 
} 

Это не дает, как много времени компиляции безопасности для моей симпатии, но это альтернатива и сохраняет большую часть ответственности базовый класс. Но я считаю, что это не так легко обнаружить, как реализация пустого метода в вашем базовом классе.

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

@protocol PickerProtocol <NSObject> 
- (void)showPicker; 
@end 

@interface SomeBaseClass : UIViewController 
    ... 
@end 

@implementation SomeBaseClass 

- (void)someBaseClassMethod { 
    if ([self conformsToProtocol:@protocol(Picker)]) { 
    [(id<PickerProtocol>)self showPicker]; 
    } 
} 

@end 

Ваших подклассы выбирают в объявляя, что они реализовали протокол, что позволяет компилятору предупредить, если вы не выполнили все @required метод.

@interface MySubClass <PickerProtocol> 
    ... 
@end 

@implementation MySubClass 

- (void)showPicker { 
    ... 
} 

@end 

Это позволяет компилятору показывать предупреждения и завершение кода. Хотя это не так просто, как пустые методы базового класса, это позволяет подклассам явно заявлять, что они предлагают некоторое поведение.

Если это только метод здесь или там, я бы использовал метод пустой метод. Если у вас есть группы методов, которые должны быть реализованы вместе, я бы использовал протоколы.

+0

Отличный ответ! Я думаю, что я буду придерживаться метода пустых методов, поскольку именно этот метод мне нужен. Еще раз спасибо! –

1

Создание класса, предназначенного для подкласса, будет работать, и это не так (большинство фреймворков зависит от таких классов).Независимо от того, действительно ли это лучший вариант для вас, зависит от того, как вы ожидаете, что класс будет использоваться.

подклассов имеет смысл, если:

  • Вы хотите, чтобы обеспечить реализацию по умолчанию этих методов.
  • Вы хотите, чтобы подкласс мог переопределять и заменять реализацию по умолчанию, контролируя, когда и когда нужно позвонить супер.
  • Это сообщение относится только к принимающему классу, например, если результирующее действие обычно взаимодействует с частными методами или свойствами контроллера. Предоставление его другим объектам приведет к жесткой связи между ними и нарушит принцип единой ответственности.

С другой стороны, делегат может быть лучшим выбором, если:

  • Такое поведение не является обязательным.
  • Сообщение является частью проблемы, которая не является ответственностью отправляющего класса. Возможно, контроллер определил намерение пользователей («выберите этот вариант»), но действие этого намерения не является его работой. Обратите внимание, что объект может быть его собственным делегатом, если это необходимо (например, для обеспечения поведения по умолчанию, а не для дефолта, для делегата nil.)
  • Для одного объекта можно ответить на это сообщение из многих источников.
  • Важно не переопределять поведение передающего объекта. «Должен назвать супер» - не очень хороший образец, несмотря на то, что он несколько раз появляется в UIKit.

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

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