我正在浏览 Programming with Objective-C Apple 提供的文档。
我正在尝试理解以下段落,但到目前为止,无法理解。
@protocol XYZPieChartViewDataSource
- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
@required
- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;
@kết thúc
@interface XYZPieCharView : UIView
@property (weak) id dataSource;
// some additional stuff
@kết thúc
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
,编译器将抛出错误。发送 respondsToSelector:
方法,lớp học
方法,或任何其他熟悉的基本 NSObject 实例方法!试试看。
这看起来很奇怪,因为 NHẬN DẠNG
应该允许任何(已知的)消息发送给它。然而,id
被认为是一个完全特定的类型;编译器将仅 允许属于 XYZPieChartViewDataSource 协议(protocol)一部分的消息。一种现代解决方案是:不要使用
id
相反,使用
NSObject*
这导致 NSObject 的所有优点都包含在这个对象中(就编译器而言),包括响应 respondsToSelector:
的能力。和 lớp học
诸如此类。
这是我在书中插入的一段,讨论了这个问题:
Curiously, the compiler treats an object typed as id
very differently from how it treats an object typed as NHẬN DẠNG
, 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
. Then if obj
is a MyClass instance, you can't speak of [obj.delegate class]
; the compiler complains that lớp học
is not a known instance method! That's because obj.delegate
is typed as id
, 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 NHẬN DẠNG
; a more elegant solution, when the definition of MyClass is up to us, is to declare the delegate
property as NSObject*
instead of id
.
Tôi là một lập trình viên xuất sắc, rất giỏi!