[Objective-C] Protocol 简介

转载 2015年07月10日 09:41:00

转自:http://rypress.com/tutorials/objective-c/protocols


A protocol is a group of related properties and methods that can be implemented by any class. They are more flexible than a normal class interface, since they let you reuse a single API declaration in completely unrelated classes. This makes it possible to represent horizontal relationships on top of an existing class hierarchy.

【yasi】protocol 定义一组相关属性和方法,protocol自己不做实现。任意类都可以遵从同一个protocol,并实现其方法。这样可以使得,不相关的任何类都遵从同一套协议,在运行时具有灵活性。

Unrelated classes adopting the StreetLegal protocol

This is a relatively short module covering the basics behind working with protocols. We’ll also see how they fit into Objective-C’s dynamic typing system.

Creating Protocols

Like class interfaces, protocols typically reside in a .h file. To add a protocol to your Xcode project, navigate to File > New> File… or use the Cmd+N shortcut. Select Objective-C protocol under theiOS > Cocoa Touch category.


Creating a protocol in Xcode

In this module, we’ll be working with a protocol called StreetLegal. Enter this in the next window, and save it in the project root.

Our protocol will capture the necessary behaviors of a street-legal vehicle. Defining these characteristics in a protocol lets you apply them to arbitrary objects instead of forcing them to inherit from the same abstract superclass. A simple version of the StreetLegalprotocol might look something like the following:

// StreetLegal.h
#import <Foundation/Foundation.h>

@protocol StreetLegal <NSObject>

- (void)signalStop;
- (void)signalLeftTurn;
- (void)signalRightTurn;

@end

Any objects that adopt this protocol are guaranteed to implement all of the above methods. The <NSObject> after the protocol name incorporates the NSObject protocol (not to be confused with theNSObject class) into the StreetLegal protocol. That is, any objects conforming to the StreetLegal protocol are required to conform to the NSObject protocol, too.

Adopting Protocols

The above API can be adopted by a class by adding it in angled brackets after the class/superclass name. Create a new classed calledBicycle and change its header to the following. Note that you need to import the protocol before you can use it.

【yasi】通过类似 @interface Bicycle: NSObject<StreatLega> 的方式就可以让 Bicyle 类遵从 StreetLegal 协议。遵从协议的类必须确保实现 protocol 中的所有 @required 方法,可以选择实现 @optional 方法

// Bicycle.h
#import <Foundation/Foundation.h>
#import "StreetLegal.h"

@interface Bicycle : NSObject <StreetLegal>

- (void)startPedaling;
- (void)removeFrontWheel;
- (void)lockToStructure:(id)theStructure;

@end

Adopting the protocol is like adding all of the methods inStreetLegal.h to Bicycle.h. This would work the exact same way even if Bicycle inherited from a different superclass. Multiple protocols can be adopted by separating them with commas (e.g., <StreetLegal, SomeOtherProtocol>).

There’s nothing special about the Bicycle implementation—it just has to make sure all of the methods declared by Bicycle.h andStreetLegal.h are implemented:

// Bicycle.m
#import "Bicycle.h"

@implementation Bicycle

- (void)signalStop {
    NSLog(@"Bending left arm downwards");
}
- (void)signalLeftTurn {
    NSLog(@"Extending left arm outwards");
}
- (void)signalRightTurn {
    NSLog(@"Bending left arm upwards");
}
- (void)startPedaling {
    NSLog(@"Here we go!");
}
- (void)removeFrontWheel {
    NSLog(@"Front wheel is off."
          "Should probably replace that before pedaling...");
}
- (void)lockToStructure:(id)theStructure {
    NSLog(@"Locked to structure. Don't forget the combination!");
}

@end

Now, when you use the Bicycle class, you can assume it responds to the API defined by the protocol. It’s as though signalStop,signalLeftTurn, and signalRightTurn were declared in Bicycle.h:

【yasi】对遵从同一个protocol的多个类的对象,都可以调用protocol中任何方法

// main.m
#import <Foundation/Foundation.h>
#import "Bicycle.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Bicycle *bike = [[Bicycle alloc] init];
        [bike startPedaling];
        [bike signalLeftTurn];
        [bike signalStop];
        [bike lockToStructure:nil];
    }
    return 0;
}

Type Checking With Protocols

Just like classes, protocols can be used to type check variables. To make sure an object adopts a protocol, put the protocol name after the data type in the variable declaration, as shown below. The next code snippet also assumes that you have created a Car class that adopts the StreetLegal protocol:

// main.m
#import <Foundation/Foundation.h>
#import "Bicycle.h"
#import "Car.h"
#import "StreetLegal.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        id <StreetLegal> mysteryVehicle = [[Car alloc] init];
        [mysteryVehicle signalLeftTurn];
        
        mysteryVehicle = [[Bicycle alloc] init];
        [mysteryVehicle signalLeftTurn];
    }
    return 0;
}

It doesn’t matter if Car and Bicycle inherit from the same superclass—the fact that they both adopt the StreetLegal protocol lets us store either of them in a variable declared with id <StreetLegal>. This is an example of how protocols can capture common functionality between unrelated classes.

Objects can also be checked against a protocol using theconformsToProtocol: method defined by the NSObject protocol. It takes a protocol object as an argument, which can be obtained via the @protocol() directive. This works much like the @selector()directive, but you pass the protocol name instead of a method name, like so:

【yasi】可以通过 conformsToProtocol 方法判断一个类的对象是否遵从某个 protocol,如果遵从,则对该对象执行protocol 中的方法

if ([mysteryVehicle conformsToProtocol:@protocol(StreetLegal)]) {
    [mysteryVehicle signalStop];
    [mysteryVehicle signalLeftTurn];
    [mysteryVehicle signalRightTurn];
}

Using protocols in this manner is like saying, “Make sure this object has this particular set of functionality.” This is a very powerful tool for dynamic typing, as it lets you use a well-defined API without worrying about what kind of object you’re dealing with.

Protocols In The Real World

A more realistic use case can be seen in your everyday iOS and OS X application development. The entry point into any app is an “application delegate” object that handles the major events in a program’s life cycle. Instead of forcing the delegate to inherit from any particular superclass, the UIKit Framework just makes you adopt a protocol:

@interface YourAppDelegate : UIResponder <UIApplicationDelegate>

As long as it responds to the methods defined byUIApplicationDelegate, you can use any object as your application delegate. Implementing the delegate design pattern through protocols instead of subclassing gives developers much more leeway when it comes to organizing their applications.

You can see a concrete example of this in the Interface Builderchapter of Ry’s Cocoa Tutorial. It uses the project’s default app delegate to respond to user input.

Summary

In this module, we added another organizational tool to our collection. Protocols are a way to abstract shared properties and methods into a dedicated file. This helps reduce redundant code and lets you dynamically check if an object supports an arbitrary set of functionality.

You’ll find many protocols throughout the Cocoa frameworks. A common use case is to let you alter the behavior of certain classes without the need to subclass them. For instance, the Table View,Outline View, and Collection View UI components all use a data source and delegate object to configure their internal behavior. The data source and delegate are defined as protocols, so you can implement the necessary methods in any object you want.

The next module introduces categories, which are a flexible option for modularizing classes and providing opt-in support for an API.


相关文章推荐

Objective-c Category和Protocol

  • 2012-07-09 10:44
  • 1.06MB
  • 下载

objective-c---ARC、block、协议(protocol)

ARCARC概念 Automatic Reference Counting :自动引用计数 ARC的判断准则 只要没有强指针指向对象,就会释放对象 指针分为两种 1、强指针:默认情况下,所有的指针...

深入理解Objective-C:Protocol(略带了解预编译)

1 、Protocol介绍Protocol为进行网络中的数据交换而建立的规则、标准或约定。用于不同系统中实体间的通信。两个实体要想通信,必须有“同一种语言”,而且,对于通信内容,怎样通信和何时通信,都...

Objective-C加强-block代码块和protocol协议

一、block代码块 block是一个变量,这个变量类似c语言中的函数指针,在回调场合用的特别多。它可以封装代码,有返回值有形参 //没有返回值没有形参的block void (^myblock)()...

objective-C学习笔记(六):OC之block和protocol

一、Block代码块        代码块的本质与其他变量类似,但是代码块存储的是一个函数体。        首先我们要知道block代码块的语法标记:脱字符(^)        ...

Objective-C分类 (category),扩展(Extension)和协议(protocol)

@类目-分类(category) 1.类目: 类目(也成类别:Category)是一种为现有类添加新方法的方式 2.类目的局限性: 1)类目无法向已有的类中添加实利变量; 2)如果类目中的方法和已有类...

Objective-C——消息、Category和Protocol

面向对象永远是个可以吐槽的话题,从开始提出到推崇备至,到充满质疑,一路走来让人唏嘘不已。面向对象的思想可谓历史悠久,20世纪70年代的Smalltalk可以说是面向对象语言的经典,直到今天我们依然将这...

Objective-C中的Protocol

Objective-C中的Protocol Protocol   简单来说就是一系列方法的列表,其中声明的方法可以被任何类实现,这种模式一般称为(delegation)模式 在iOS中和OS X中,...

Objective-C 13 协议protocol

Objective-C中的协议@protocol,与java中的接口interface类似,其中列出的方法,本类不需要实现,而由实现此协议的类来实现这些方法。 1 声明协议protocol 格式: @...

黑马程序员——Objective-c——block和protocol

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- Block的掌握 1、如何定义block变量     int (^sumBlock)(i...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)