Неофициальный Протокол В цели-C?

Я задавался вопросом, может ли кто-то объяснить, что такое неофициальные протоколы в Objective C? Я пытаюсь понять это на документации яблока и некоторых других книгах, но моя голова все еще вращается так, я буду действительно ценить это, если кто-то может объяснить с примером.

Спасибо.

51
задан itsaboutcode 5 January 2010 в 13:59
поделиться

5 ответов

Неформальный протокол , как сказал Джоннатан, обычно был категорией, объявленной в NSObject без соответствующей реализации (чаще всего - был редкий протокол, который предоставлял фиктивные реализации на NSObject).

Начиная с версии 10.6 (и в iPhone SDK) этот шаблон больше не используется. В частности, то, что было объявлено следующим образом в 10.5 (и ранее):

@interface NSObject(NSApplicationNotifications)
- (void)applicationWillFinishLaunching:(NSNotification *)notification;
...
@interface NSObject(NSApplicationDelegate)
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
...

Теперь объявлено как:

@protocol NSApplicationDelegate <NSObject>
@optional
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
...
- (void)applicationWillFinishLaunching:(NSNotification *)notification;
...

То есть, неофициальные протоколы теперь объявлены как @protocol s с набором @optional методы.

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

59
ответ дан 7 November 2019 в 10:12
поделиться

Весь неформальный протокол - это категория на каком-то классе (часто NSObject), которая определяет интерфейс протокола. AppKit часто использует это для делегирования.

Подкласс, который Вы пишете, может реализовать эти методы. Разница между этим и формальным протоколом заключается в том, что формальные протоколы объявляются с помощью @protocol ... @end. Нет никакой проверки, реализует ли класс @protocol заданный неформальный протокол.

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

.
4
ответ дан 7 November 2019 в 10:12
поделиться

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

.
1
ответ дан 7 November 2019 в 10:12
поделиться

Одним из распространенных примеров неформальных протоколов является определение обратных вызовов. Предположим, вы используете библиотеку, которая позволяет загрузить что-то в фоновом режиме. Эта библиотека позволяет вам зарегистрировать объект обратного вызова, который будет вызван после завершения загрузки.

- (void)download:(NSURL*)url whenComplete:(id)callback

Когда загрузка завершена, она вызовет определенный метод для вашего объекта обратного вызова:

- (void)downloadComplete:(NSURL*)url

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

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

Начиная с Objective-C 2.0, формальные протоколы могут содержать необязательные методы. Кроме того, Apple может отходить от неформальных протоколов для новых API - UIAccelerometerDelegate является формальным протоколом.

.
9
ответ дан 7 November 2019 в 10:12
поделиться

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

Документация Apple:

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

#import <Foundation/Foundation.h>

@interface Cat1 : NSObject {


}
- (void) simpleMethod;

@end

@implementation Cat1

- (void) simpleMethod
{

    NSLog(@"Simple Method");
}

@end


@interface Cat1 (Cat2) 
- (void) addingMoreMethods;

@end




@interface MYClass : Cat1

@end

@implementation MYClass

- (void) addingMoreMethods
{
    NSLog(@"Testing!");
}
@end

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


    MYClass *myclass = [[MYClass alloc] init];
    [myclass addingMoreMethods];
    [myclass release];
    [pool drain];
    return 0;
}
3
ответ дан 7 November 2019 в 10:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: