Подтвердить что ты не робот

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

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

Спасибо.

4b9b3361

Ответ 1

Неформальный протокол был, как сказал Джуннатан, как правило, категорией, объявленной в 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 с помощью набора методов @optional.

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

Ответ 2

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

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

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

- (void)downloadComplete:(NSURL*)url

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

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

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

Ответ 3

Мы определяем informal protocol, группируя методы в объявлении категории,

@interface NSObject ( MyXMLSupport )
- initFromXMLRepresentation:(NSXMLElement *)XMLElement;
- (NSXMLElement *)XMLRepresentation;
@end

informal protocol обычно объявляются категориями класса NSObject, поскольку это широко ассоциируется имя метода с любым классом, который наследует от NSObject.

Поскольку все классы наследуются от корневого класса, методы arent ограничены любой частью иерархии наследования. (Можно было бы также объявить a informal protocol как категорию другого класса, чтобы ограничить его определенной ветвью иерархии наследования, но для этого мало оснований).

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

Ответ 4

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

Поэтому может возникнуть одно сомнение

Будет ли он неофициальным протоколом, если есть какие-либо дополнительные методы для самого протокола?

Ответ - нет.

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

Примечание:

В объекте c 2.0 были введены дополнительные методы в протоколе, поэтому до этого цель была достигнута посредством неофициального протокола I.e посредством категории.

Категория:

Это функция уровня языка, которая должна быть альтернативой для подкласса aka inheritance.

Я надеюсь, что он проливает свет извести на это.

Ответ 5

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

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

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

Ответ 6

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

Документация 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;
}

Ответ 7

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