Iphone 使用id<;代表>;作为函数的属性或参数

Iphone 使用id<;代表>;作为函数的属性或参数,iphone,objective-c,Iphone,Objective C,所以我不确定这是怎么回事。我简单地看了一下同事的C#(我不是.NET开发人员),我看到很多传递到方法中的东西都是符合接口的类对象。这在objective-c中也是一件好事吗 例如,我正在摆弄MapKit API,我创建了自己的类,该类符合MKAnnotation协议,这样我就可以拥有自定义视图和一些额外的属性,用于在地图上删除的典型pin。我计划使用我创建的这个类 Address : NSObject 与我在地图上放置图钉时的MKPlacemark类相反。在我的其他视图控制器和模型类中,我是否

所以我不确定这是怎么回事。我简单地看了一下同事的C#(我不是.NET开发人员),我看到很多传递到方法中的东西都是符合接口的类对象。这在objective-c中也是一件好事吗

例如,我正在摆弄MapKit API,我创建了自己的类,该类符合MKAnnotation协议,这样我就可以拥有自定义视图和一些额外的属性,用于在地图上删除的典型pin。我计划使用我创建的这个类

Address : NSObject
与我在地图上放置图钉时的MKPlacemark类相反。在我的其他视图控制器和模型类中,我是否执行以下操作:

@property (nonatomic, strong) id <MKAnnotation> object; //1 

我从示例1开始,但当我实际需要Address对象的一些属性时,我发现自己无论如何都必须对该对象进行类型转换,这似乎有什么意义,或者我没有抓住要点?所以我想我的最终问题是,1还是2更好,在什么情况下?谢谢。

我会选择选项3,它看起来像这样:

Address : NSObject <MKAnnotation>
地址:NSObject
然后,在实现该类时,实现符合
MKAnnotation
协议所需的方法

这样你就能两全其美


协议与C#或Java等语言中的接口非常相似。其中一个主要区别是需要某些方法,而其他方法是可选的。由于Objective-C是一种动态语言,您将看到许多调用,例如
[foo responseToSelector:@selector(someSelector:)]
。如果
-someSelector:
标记为可选,则需要检查接收者是否“响应”该消息。但是,如果它被标记为required,那么如果您没有实现该方法,编译器将抛出一条警告。查看,了解更多信息

您不能对id类型使用强关键字,请改为使用此关键字:

@property (nonatomic, assign, readwrite) id<MyDelegate> delegate;
@属性(非原子、赋值、读写)id委托;

我对对象这样做,但当涉及到使用属性或符合协议的对象时,我不知道如何访问该类,因为我的Address类的属性无法识别,除非我将该类键入Address对象。谢谢。如果是这样的话,请声明您的地址对象符合协议,并像平时一样使用地址对象。这有意义吗?为了进一步解释为什么会使用一个而不是另一个:当使用MapKit之类的东西时,API设计者声明了某些协议来创建一个对象要遵守的契约。API不关心传入的对象类型,只要它符合特定的协议。在本例中,您似乎将地址对象作为模型对象传递。这是完全可以的,直到你需要更通用的东西。然后,您可以根据需要扩展协议或提出继承模型。98%的时间里更简单更好。我仍然没有掌握的部分是,如果我使用选项3,假设我想迭代一些对象数组,那么我会这样做:
for(id obj in array){[obj???]}
除非我强制转换
obj
,或者使用
if,否则我将无法访问属性([objrespondsToSelector@selector(someMethod:)]{[obj someMethod]}
对吗?您还可以询问该对象是否是某个类的实例。您可以通过以下方式执行:
[obj iskindof类:[Address class]]
.Objective-C与任何其他具有多态性和继承性的面向对象语言一样。如果不需要使用MKAnnotation,则使用地址实例。在这种情况下,它们是一样的。MapKit只关心是否符合
MKAnnotation
协议,您的应用程序只关心它是否是的实例de>Address。选择最适合您的应用程序的方法。您完全可以将类型为
id
的对象标记为retain或strong。如果存在这样的关系,您将遇到的问题是有一个retain循环。Crystal似乎没有在此处使用委派,因此具有strong或retain类型的属性是完全有效的。但是建议不要为代表使用strong/retain。那么,为什么要冒险将其创建为strong,即使它没有在其他任何地方使用,并且开发人员知道没有保留周期?
@property (nonatomic, assign, readwrite) id<MyDelegate> delegate;