gpt4 book ai didi

ios - 符合协议(protocol)的 id 与使用协议(protocol)限定 id

转载 作者:可可西里 更新时间:2023-11-01 06:23:10 27 4
gpt4 key购买 nike

我正在浏览 Programming with Objective-C Apple 提供的文档。

我正在尝试理解以下段落,但到目前为止,无法理解。

@protocol XYZPieChartViewDataSource
- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
@required
- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;
@end

@interface XYZPieCharView : UIView
@property (weak) id <XYZPieChartViewDataSource> dataSource;
// some additional stuff
@end

If you attempt to call the respondsToSelector: method on an id conforming to the protocol as it’s defined above, you’ll get a compiler error that there’s no known instance method for it. Once you qualify an id with a protocol, all static type-checking comes back; you’ll get an error if you try to call any method that isn’t defined in the specified protocol. One way to avoid the compiler error is to set the custom protocol to adopt the NSObject protocol.

我对“符合协议(protocol)”和“使用协议(protocol)限定某些对象”之间的区别感到困惑。如果我们发送符合协议(protocol)的 id - respondsToSelector 消息,为什么编译器会生成错误?

最佳答案

And why should compiler generate an error if we send an id - that conforms to the protocol - the respondsToSelector message

是的,这是一件很奇怪的事情。如今,在 ARC 下,如果对象声明为 id <XYZPieChartViewDataSource>,编译器将抛出错误。发送 respondsToSelector:方法,class方法,或任何其他熟悉的基本 NSObject 实例方法!试试看。

这看起来很奇怪,因为 id应该允许任何(已知的)消息发送给它。然而,id <XYZPieChartViewDataSource>被认为是一个完全特定的类型;编译器将 允许属于 XYZPieChartViewDataSource 协议(protocol)一部分的消息。一种现代解决方案是:不要使用

id <XYZPieChartViewDataSource>

相反,使用

NSObject<XYZPieChartViewDataSource>*

这导致 NSObject 的所有优点都包含在这个对象中(就编译器而言),包括响应 respondsToSelector: 的能力。和 class诸如此类。

这是我在书中插入的一段,讨论了这个问题:

Curiously, the compiler treats an object typed as id<SomeProtocol> very differently from how it treats an object typed as id, allowing only methods defined in SomeProtocol to be sent to that object. For example, suppose MyClass is defined with a delegate property typed as id<MyProtocol>. Then if obj is a MyClass instance, you can't speak of [obj.delegate class]; the compiler complains that class is not a known instance method! That's because obj.delegate is typed as id<MyProtocol>, and thus its only known instance method is doSomething:, the method defined by MyProtocol. We can work around this by casting obj.delegate to an id; a more elegant solution, when the definition of MyClass is up to us, is to declare the delegate property as NSObject<MyProtocol>* instead of id<MyProtocol>.

关于ios - 符合协议(protocol)的 id 与使用协议(protocol)限定 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22794634/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com