这是运行泛型方法的正确方法吗?

时间:2015-03-04 23:17:06

标签: ios objective-c macos cocoa cocoa-touch

我有这个方法应该设置对象的名称,但对象可以是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而我们又回到原点。同样的错误。

我有什么更好/更优雅的方法呢?

4 个答案:

答案 0 :(得分:5)

使用A,B和C类都符合的协议。

@protocol MyProtocol <NSObject>
@required
- (void)setName:(NSString *)name;
@end

然后

id<MyProtocol> object = ...
[object setName:newName];

答案 1 :(得分:1)

更好的方法是让ABC实现定义方法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];
}