Почему django осуществляет все образцовые классы, чтобы быть в models.py?

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

, Например, предположите, что Вы имеете UIWebView. Если требуется реализовать его делегата webViewDidStartLoad: метод, Вы могли бы создать класс как это:

@interface MyClass
// ...
@end

@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView { 
    // ... 
}
@end

Тогда Вы могли создать экземпляр MyClass и назначить его делегатом веб-представления:

MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;

На UIWebView сторона, это, вероятно, имеет код, подобный этому, чтобы видеть, отвечает ли делегат webViewDidStartLoad: сообщение с помощью [1 129] respondsToSelector: , и отправьте его при необходимости.

if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
    [self.delegate webViewDidStartLoad:self];
}

само свойство делегата обычно объявляется weak (в ARC), или assign (предварительный ARC) для предотвращения сохраняют циклы, так как делегат объекта часто держит сильную ссылку к тому объекту. (Например, контроллер представления часто является делегатом представления, которое он содержит.)

Делегаты Создания к Вашим Классам

Для определения собственных делегатов необходимо будет объявить их методы где-нибудь, как обсуждено в Документы Apple о протоколах . Вы обычно объявляете формальный протокол. Объявление, перефразируемое от UIWebView.h, было бы похоже на это:

@protocol UIWebViewDelegate 
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end

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

@interface MyClass 
// ...
@end

И затем реализуют методы в протоколе. Для методов, объявленных в протоколе как [1 116] (как большинство методов делегата), необходимо свериться -respondsToSelector: прежде, чем назвать конкретный метод на нем.

Именование

Методы делегата обычно называют, начиная с имени класса делегирования и берут объект делегирования в качестве первого параметра. Они также часто используют желание - должен - или сделал - форма. Так, webViewDidStartLoad: (первый параметр является веб-представлением), а не loadStarted (берущий параметры), например.

Оптимизация Скорости

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

@protocol SomethingDelegate 
@optional
- (void)something:(id)something didFinishLoadingItem:(id)item;
- (void)something:(id)something didFailWithError:(NSError *)error;
@end

@interface Something : NSObject
@property (nonatomic, weak) id  delegate;
@end

@implementation Something {
  struct {
    unsigned int didFinishLoadingItem:1;
    unsigned int didFailWithError:1;
  } delegateRespondsTo;
}
@synthesize delegate;

- (void)setDelegate:(id )aDelegate {
  if (delegate != aDelegate) {
    delegate = aDelegate;

    delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
    delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
  }
}
@end

Затем в теле, мы можем проверить, что наш делегат обрабатывает сообщения путем доступа к нашему delegateRespondsTo структура, а не путем отправки -respondsToSelector: много раз.

Неофициальные Делегаты

Перед протоколами существовали, было распространено использовать категория на [1 122] для объявления методов, которые мог реализовать делегат. Например, CALayer все еще делает это:

@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end

Это по существу говорит компилятору, что любой объект мог бы реализовать displayLayer:.

Вы тогда использовали бы тот же -respondsToSelector: подход, как описано выше для вызова этого метода. Делегаты просто реализуют этот метод и присваиваются delegate свойство, и вот именно (нет никакого объявления, что Вы соответствуете протоколу). Эта методика является общепринятой в библиотеках Apple, но новый код должен использовать более современный подход протокола выше, так как этот подход загрязняет NSObject (который делает автоматическое заполнение менее полезным), и мешает компилятору предупреждать Вас об опечатках и подобных ошибках.

12
задан Mert Nuhoglu 27 August 2009 в 05:35
поделиться