非正式协议在Objective-C?

我想知道是否有人可以解释目标C中的非正式协议? 我尝试了解苹果文档和其他一些书籍,但是我的头仍然在旋转,所以我会很感激,如果有人可以用例子来解释。

谢谢。

正如Jonnathan所说,一个非正式的协议通常是在NSObject上声明的一个类别,没有相应的实现(通常很less有提供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方法。

在任何情况下,非正式协议都是方法声明的集合,您可以select实现方法来更改行为。 通常(但并非总是),在委托的上下文中提供方法实现(例如,表视图的数据源必须实现less数所需的方法,并可以select实现一些附加的方法)。

给出非正式协议的一个常见例子是定义callback。 假设你正在使用一个库,可以让你在后台下载一些东西。 这个库允许你注册一个完成时被调用的callback对象。

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

下载完成后,它会在您的callback对象中调用一个特定的方法:

 - (void)downloadComplete:(NSURL*)url 

当然,不能保证你的callback对象实际上实现了这个方法。 非正式协议使用一个类别在NSObject上提供了这些方法的简单实现。 因此,系统中的所有对象都将响应downloadComplete:方法,尽pipe默认情况下它们不会响应该方法。 覆盖downloadComplete:方法的类可以提供更多有用的function。

到目前为止,你可以用一个正式的协议完成同样的事情。 但是,非正式的协议允许你有可选的方法。 实现正式协议的类必须为协议中的每个方法提供一个实现。 实现非正式协议的类可以省略任何方法的实现 – 它已经从NSObjectinheritance了一个实现。

自Objective-C 2.0以来,正式的协议可以包含可选的方法。 此外,苹果可能正在从新的API的非正式协议 – UIAccelerometerDelegate是一个正式的协议。

我们通过在类别声明中分组方法来定义一个informal protocol

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

Informal protocol通常被声明为NSObject类的类别,因为它广泛地将方法名称与从NSObjectinheritance的任何类相关联。

因为所有的类都是从根类inheritance的,所以这些方法并不局限于inheritance层次结构的任何部分。 (也可以声明一个informal protocol作为另一个类的一个类来限制它到inheritance层次的某个分支,但是没有理由这样做)。

当用来声明协议时,类别接口没有相应的实现。 相反,实现该协议的类再次在自己的接口文件中声明方法,并在其实现文件中将其与其他方法一起定义。

非正式协议是一种通过类别 将可选方法添加到对象的方法

所以可能会出现一个疑问

如果协议本身有任何可选的方法,它会成为非正式协议吗?

答案是不。

如果这些方法是在协议中声明的,并且它被认为符合一个类而没有任何类别的使用,那么它就是正式的协议

注意:

在目标c 2.0中引入了协议中的可选方法,以便通过非正式协议Ie通过类别实现目的。

类别:

这是一个语言级别的function,旨在替代子类inheritance。

我希望能够在这里发表一些暗示。

所有非正式协议都是一些类(通常是NSObject )的一个类,它声明了协议的接口。 AppKit为其代表团使用了很多。

您编写的子类可以实现这些方法。 这和正式协议的区别在于正式的协议是使用@protocol ... @end notation声明的。 没有检查一个类是否执行给定的非正式协议。

我几乎总是使用正式的协议,但是我想如果你想提供默认的行为(只是提供一个可以覆盖你的类的实现),一个非正式的协议是有用的。

基于“乔纳森·斯特林”的答案,我可以说下面的代码代表非正式的协议?

苹果文档:

“当用来声明协议时,类别接口没有相应的实现,相反,实现该协议的类再次在自己的接口文件中声明方法,并在其实现文件中将其与其他方法一起定义。

 #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; } 

一个非正式的协议定义了对象必须理解的方法。 这被称为“符合协议”。 符合协议是独立于类层次结构的。 当声明一个指针来保存一个对象的引用时,你可以定义这个对象应符合哪个协议。 如果您编写的代码指定的对象不符合所有必需的协议,则会在编译时收到警告。 非正式的协议可以帮助您依赖对象理解的一组方法。 您不必在您的代码中调用isKindOfClass:或respondsTo:来检查传入的对象是否适合您的处理。 协议是一种面向方面的编程。