当你使用 @selector() 检索选择器的 ID 时,选择器的值是否会根据参数的类型而有所不同?
这就是我的意思。我有一个方法,它接受一个对象引用和一个选择器,然后用一个参数调用它:
-(void)CallLaterNSObject*) Obj Sel: (SEL)Sel
{
//Some stuff, then:
[Obj performSelector: Sel withObject: SomeOtherObject];
}
我将这个方法与一个选择器一起使用到一个函数,该函数接受一个类型化的对象引用,而不是一个 id :
-(void)MyMethod: (MyObject*) a
{
}
[self CallLater: self Selselector(MyMethod];
这似乎奏效了,但我的感觉很刺痛。在像 C# 这样的静态类型语言中,这将是一个错误,一个向上转型 - CallLater 期望一个函数的选择器接受一个 id 并且我给它一个函数这需要一个 MyObject 。
另一方面,编译器不会提示,id 和具体的对象引用似乎都只是深层的指针,可以简单地相互转换。话又说回来,Objective C 编译器没有提示的错误有很多。
所以真正的问题是 - 它安全吗?欢迎语言律师。
Best Answer-推荐答案 strong>
这是安全的;对象是对象。 NSObject * 的选择器参数与 MyObject * 的选择器参数完全相同。
如果您希望 MyMethod 验证它是使用特定类型的对象调用的,它应该对其执行 NSParameterAssert:
NSParameterAssert([obj isKindOfClass: [MyObject class]]);
就我个人而言,我很少做这个检查。实际对象 acts 就像我想要的类型就足够了,如果不是,我会得到一个运行时错误(通常是无法识别的选择器)。在简单的情况下,您会收到编译器警告,值得关注此警告(并在必要时使用 id 强制转换使其静音)。
我对您在问题中使用 id 感到有些困惑,所以我想确保您理解这一点:NSObject * 完全一样id 作为 MyObject * 是。 id 是一个通用实例指针类,而 NSObject * 是一个 NSObject 实例(或 NSObject 的子类) .您可以拥有不来自 NSObject 的对象。但您可能永远不必知道这一点。
其他说明,重新:约定:
- 选择器(名称和参数)以小写字母开头,因此
CallLater:Sel: 应该是 callLater:sel: 。
- 变量和参数名称以小写字母开头;上面的
Obj 应该是obj 。
- 类名确实以大写字母开头。
关于objective-c - 选择器 ID 对参数类型敏感吗?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/11571781/
|