Objective c 为变量声明协议的目的是什么?

Objective c 为变量声明协议的目的是什么?,objective-c,protocols,ivar,ivars,Objective C,Protocols,Ivar,Ivars,我一直在阅读有关Objective-C的协议,但我无法理解这一点: 以这条线为例 Person <CoordinateSupport> *person = [[Person alloc] init]; Person*Person=[[Person alloc]init]; 声明变量以符合协议协调支持的目的是什么?这仅仅是为了编译时,所以如果我给person分配了不同的内容,Xcode可以警告我,或者在运行时有什么目的吗 我看不出变量如何符合协议。好的,一个类很容易看到,因为你可以

我一直在阅读有关Objective-C的协议,但我无法理解这一点:

以这条线为例

Person <CoordinateSupport> *person = [[Person alloc] init];
Person*Person=[[Person alloc]init];
声明变量以符合协议协调支持的目的是什么?这仅仅是为了编译时,所以如果我给
person
分配了不同的内容,Xcode可以警告我,或者在运行时有什么目的吗

我看不出变量如何符合协议。好的,一个类很容易看到,因为你可以有一个协议定义方法,你希望某个类遵循这个方法,但是一个ivar


我没有看到它。

声明变量符合协议时的标准模式是为其指定“任意对象”类型,
id
。声明一个变量既有特定类型又符合协议通常是多余的——我将在后面解释原因。现在,让我们来讨论
id

类型的变量,其中
P
是一些协议,以及它们为什么有用。此类型应理解为“符合
P
的任何类的实例”

为了将下面的讨论具体化,让我们定义一个协议:

@protocol Adder
- (NSInteger)add:(NSInteger)a to:(NSInteger)b;
@end
我看不出变量如何符合协议

这个很简单。当变量表示实现协议中所有必需方法的类的实例时,它符合Objective-C协议

@interface Abacus : NSObject <Adder>
@end

@implementation Abacus
- (NSInteger)add:(NSInteger)a to:(NSInteger)b { return a + b; }
- (NSInteger)beadCount { return 91; }
@end
但是您也可以将
a
声明为
id类型,在某些情况下,您希望讨论一个实例,该实例要么是给定的类,要么是其子类,并且还指定它符合协议,但这种情况很少见,并且通常不需要同时指定类和协议一致性


有关更多信息,请参阅苹果指南

如果是
id person=…
,对我来说会更有意义。我已经复制了它,但无论如何,如果你能用一个答案解释
id
示例……我的意思是,要么
person
实现
协调支持,要么不实现。在上面添加协议注释不会改变任何事情。然而,对于
id
,您的意思是不关心对象的类型,只关心它提供您需要的服务。因此,您的回答没有解释我为什么要这样做。我看不出没有一个例子。。。如果类已经在使用协议,为什么我要在ivar上使用该声明呢?啊…对不起。我以为你只是在问在
Person
中使用
Person
的价值,我看不出有什么价值。你真的在问关于符合协议的变量的使用吗?一般来说,“声明一个变量既有特定类型又符合协议是多余的”——不一定。请参阅我的答案以获得解释。同意。编辑以反映这一点。
Abacus *a = [[Abacus alloc] init];
NSLog(@"%ld", (long)[a add:5 to:6]);  // 11
NSLog(@"%ld", (long)[a beadCount]);   // 91
id<Adder> a = [[Abacus alloc] init];
NSLog(@"%ld", (long)[a add:5 to:6]);  // 11
NSLog(@"%ld", (long)[a beadCount]);   // Compile error: No known instance method for selector 'beadCount'
- (Abacus *)getAdder { return [[Abacus alloc] init]; }
- (void)doWork {
    Abacus *a = [self getAdder];
    // Do lots of adding...
}
- (id<Adder>)getAdder { return [[Abacus alloc] init]; }
- (void)doWork {
    id<Adder> *a = [self getAdder];
    // Do lots of adding...
}