Может ли объект подписаться на свои собственные уведомления?

#objective-c #design-patterns #uitextfield #nsnotifications #uitextfielddelegate

#objective-c #шаблоны проектирования #uitextfield #nsnotifications #uitextfielddelegate

Вопрос:

Например, a UITextField не может быть его собственным делегатом, но можно ли просто зарегистрировать его в качестве наблюдателя своих собственных уведомлений? Выглядит странно, но, похоже, работает нормально. Мысли?

 // MyTextField.h

@interface MyTextField : UITextField
@end

// MyTextField.m

@interface MyTextField ()
- (void)myTextFieldDidChange:(NSNotification *)notification;
@end

@implementation MyTextField

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(myTextFieldDidChange:)
         name:UITextFieldTextDidChangeNotification
         object:self];
    }
}

- (void)myTextFieldDidChange:(NSNotification *)notification {
    // Do custom stuff here.
}

@end
  

Комментарии:

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

2. Но описанный выше метод позволяет очистить контроллер представления и позволяет MyTextField повторно использовать его в других контроллерах представления без необходимости повторной реализации textFieldDidChange: функциональности точно таким же образом.

Ответ №1:

То, что вы делаете, кажется прекрасным, но для этого конкретного примера есть более чистое решение:

 // MyTextField.h

@interface MyTextField : UITextField
@end

// MyTextField.m

@interface MyTextField ()
- (void)myTextFieldDidChange:(UITextField *)textField;
@end

@implementation MyTextField

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self addTarget:self action:@selector(myTextFieldDidChange:)
       forControlEvents:UIControlEventEditingChanged];
    }
    return self;
}

- (void)myTextFieldDidChange:(MyTextField *)myTextField {
    // Do custom stuff here.
}

@end
  

Проверьте UIControlEvents ссылку.