在使用类似
之类的东西编写代理时,我看到了很多代码引用@property (nonatomic, weak) id<mySuperCoolDelegate> delegate;
通常id<mySuperCoolDelegate>
所在的位置是属性的数据类型。所以问题是:
我的理解是否正确,上面的语法告诉编译器数据类型的id是mySuperCoolDelegate?
可以使用这种代码(为id指定的数据类型)的其他任何示例吗?
谢谢!
答案 0 :(得分:6)
这段代码是客观实现接口的方式(如在Java或Go中)。使用&#34; id&#34;意味着你在编译时不知道它将是什么类型的对象。但是在尖括号中使用协议,你告诉编译器无论它将是什么对象,它都需要支持&#39; mySuperCoolDelegate&#34;协议。如果它没有 - 编译器会通知你。
答案 1 :(得分:2)
此语法告诉编译器delegate
是某种实现mySuperCoolDelegate
协议的类(任何类)。
这允许某个组件在发生的某些事件上通知另一个组件,而无需了解所通知的组件(按类型)。 (例如UITextView
只通过通用类型的委托通知其控制器文本已被更改而没有对该控制器的引用,因此UITextView
不需要将自己限制为特定的控制器&#39 ; s类型)
另请注意,代表通常被宣称为弱(而不是强)。如果UIViewController
的实例具有对UITextView
实例的强引用,并且该文本视图委托(假设它很强)是控制器实例,那么您将有一个保留周期,其中两个对象释放将依赖在另一个对象的发布上(这种情况永远不会发生并且会导致内存泄漏)。
答案 2 :(得分:1)
简短:
这告诉编译器该属性可以是任何类型,只要它实现协议mySuperCoolDelegate
即可。
仍然太短,无法100%准确但易于理解:
id
类似于NSObject*
,这意味着它是对任何类型对象的引用(不仅是NSObject的子类,坦率地说)。 Witin&lt;&gt;您声明对象必须符合哪些协议。
示例:可能是:
@interface mySuperCoolClass : <mySuperCoolDelegate> ... @end
或
@interface somebodyElsesSuperCoolClass : <mySuperCoolDelegate> ... @end
无论您在何处使用该属性,编译器都允许您访问在相关@protocol
中声明的所有方法(最有可能在#include
所需的某些.h文件中)。