Objective-C的.你能使用像Java接口这样的协议吗?

23 java objective-c

这些基本上是一回事吗?

例如,如果我有一个Java接口

public interface CoolObject{
 ...
}
Run Code Online (Sandbox Code Playgroud)

我可以CoolObject在函数中使用任何实现接口的对象CoolObject作为参数:

public void foo(CoolObject o) {
...
}
Run Code Online (Sandbox Code Playgroud)

Objective-C中是否相同?

@protocol CoolProtocol
...
@end

@interface Foo: NSObject <CoolProtocol>
...
@end

(void) - someMethod: (CoolProtocol *) obj {
}
Run Code Online (Sandbox Code Playgroud)

以上工作(被认为是正确的吗?)

谢谢你的时间.如果您需要我澄清我的问题,请告诉我.

Pet*_*wis 35

关.在Objective C中,您指示一个对象实现了一个带有尖括号<>的协议,因此您可以像下列其中一个一样编写您的方法:

- (void) someMethod: (id <CoolProtocol>) obj { }
- (void) someMethod: (id <NSObject, CoolProtocol>) obj { }
- (void) someMethod: (NSObject <CoolProtocol> *) obj { }
Run Code Online (Sandbox Code Playgroud)

在所有情况下,您都说someMethod需要一个实现CoolProtocol的对象.

id是指向任何类型的Objective C对象的通用指针.

所以id <CoolProtocol>意味着"任何一种实现CoolProtocol的客观C对象".

通常,您希望能够保留/释放/自动释放对象,并且通常将其视为常规Cocoa对象,因此通常也可以添加NSObject协议,这是第二种情况.

如果你想确保它实际上是一个合适的Cocoa对象(不包括基于NSProxy的对象),那么你可以使用最后一个表单,它基本上说"我想要任何实现CoolProtocol的真正Cocoa Objective C对象".

  • 好答案.一个相关的方法是让CoolProtocol采用NSObject协议,这使得id <CoolProtocol>工作得很好.最后一种形式是正确的,但通常过于冗长,因为(无意中)无法继承NSObject的对象通常会在编译时导致错误,并且它会调用静态类型,这会降低使Objective-C如此强大和灵活的动态性. (2认同)

小智 14

彼得斯的答案很棒.我想补充一点.如果您将"NSObject"协议添加到您的协议

@protocol CoolProtocol <NSObject>
@end
Run Code Online (Sandbox Code Playgroud)

这将减少您在方法声明中声明NSObject协议的需要.

- (void) someMethod: (id <NSObject, CoolProtocol>) obj { }
Run Code Online (Sandbox Code Playgroud)

现在变成了

 - (void) someMethod: (id <CoolProtocol>) obj { }
Run Code Online (Sandbox Code Playgroud)