我有这个方法应该设置对象的名称,但对象可以是3个类,A,B和C.
如果我只是这样做
[object setName: @"new name"]; //at this point I am treating object as of type id
Xcode会抱怨有多个名为" setName"的方法,然后我这样做
if ([object isKindOfClass:[ClassA class]]) {
[(ClassA *)object setName:newName];
} else
if ([object isKindOfClass:[ClassB class]]) {
[(ClassB *)object setName:newName];
} else
[(ClassC *)object setName:newName];
}
但这对我来说似乎很蹩脚。
我试图通过使用类似的东西来欺骗Xcode
[(typeof(object))object setName:newName];
但Xcode也不喜欢它,可能是因为typeof(object)
正在返回id
而我们又回到原点。同样的错误。
我有什么更好/更优雅的方法呢?
答案 0 :(得分:5)
使用A,B和C类都符合的协议。
@protocol MyProtocol <NSObject>
@required
- (void)setName:(NSString *)name;
@end
然后
id<MyProtocol> object = ...
[object setName:newName];
答案 1 :(得分:1)
更好的方法是让A
,B
和C
实现定义方法protocol
的相同setName
。
<强> NameProtocol.h 强>
@protocol NameProtocol <NSObject>
- (void)setName:(NSString *)name;
@end
<强> A.H 强>
@interface A : NSObject <NameProtocol>
<强> B.h 强>
@interface B : NSObject <NameProtocol>
<强> C.h 强>
@interface C : NSObject <NameProtocol>
答案 2 :(得分:1)
使用键值编码。
[object setValue:newName forKey:@"name"];
这是一种快速而肮脏的方式,我建议使用协议,但它在适当的环境中很有用。
<强>更新强>
KVC没有编译时类型检查:增加缺陷的可能性。运行时错误导致异常:缺陷导致应用程序崩溃。它的语法暗示object
是一个字典:隐藏代码的意图。它很晦涩:初级开发人员通常不会理解它是如何工作的,并可能导致维护问题。
这是一场真正的恐怖表演,但它在适当的环境中非常有用。
答案 3 :(得分:0)
协议是要走的路。但你也可以这样做:
if ([object respondsToSelector: @selector(setName:)])
{
[object performSelector: @selector(setName:) withObject: name];
}