这是 运行 通用方法的正确方法吗?
Is this the right way to run a generic method?
我有这个方法应该设置对象的名称,但对象可以是 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
而我们又回到了原点。同样的错误。
我有什么 better/elegant 方法可以做到这一点?
更好的方法是让 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>
使用 class A、B 和 C 都遵守的协议。
@protocol MyProtocol <NSObject>
@required
- (void)setName:(NSString *)name;
@end
然后
id<MyProtocol> object = ...
[object setName:newName];
协议是必经之路。但你也可以这样做:
if ([object respondsToSelector: @selector(setName:)])
{
[object performSelector: @selector(setName:) withObject: name];
}
使用键值编码。
[object setValue:newName forKey:@"name"];
这是一种快速而肮脏的方法,我建议使用协议,但在适当的情况下它会很有用。
更新
KVC 没有编译时类型检查:增加了出现缺陷的可能性。运行时错误导致异常:缺陷导致应用程序崩溃。它的语法暗示 object
是一个字典:隐藏代码的意图。晦涩难懂:初级开发人员通常不会理解它是如何工作的,并且可能会导致维护问题。
这是一部真正的恐怖片,但在适当的情况下会很有用。
我有这个方法应该设置对象的名称,但对象可以是 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
而我们又回到了原点。同样的错误。
我有什么 better/elegant 方法可以做到这一点?
更好的方法是让 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>
使用 class A、B 和 C 都遵守的协议。
@protocol MyProtocol <NSObject>
@required
- (void)setName:(NSString *)name;
@end
然后
id<MyProtocol> object = ...
[object setName:newName];
协议是必经之路。但你也可以这样做:
if ([object respondsToSelector: @selector(setName:)])
{
[object performSelector: @selector(setName:) withObject: name];
}
使用键值编码。
[object setValue:newName forKey:@"name"];
这是一种快速而肮脏的方法,我建议使用协议,但在适当的情况下它会很有用。
更新
KVC 没有编译时类型检查:增加了出现缺陷的可能性。运行时错误导致异常:缺陷导致应用程序崩溃。它的语法暗示 object
是一个字典:隐藏代码的意图。晦涩难懂:初级开发人员通常不会理解它是如何工作的,并且可能会导致维护问题。
这是一部真正的恐怖片,但在适当的情况下会很有用。