处理来自不同类的对象

时间:2010-10-06 18:21:19

标签: iphone objective-c

我有3类对象。所有3个类共享一些共同的属性,如颜色,文本等。

例如,我可以拥有此

Class1 *objectA = [[Class1 alloc] init];
objectA.myColor = [UIColor redColor];

Class2 *objectB = [[Class2 alloc] init];
objectA.myColor = [UIColor redColor];

Class3 *objectC = [[Class3 alloc] init];
objectA.myColor = [UIColor redColor];

......等等。

现在我需要创建一个方法来改变给定对象的颜色,无论它代表什么类。

一种典型的方法是

- (void) changeColor:(Class1*) myOBJ toColor:(UIColor*)myColor {
   myOBJ.color = myColor;
}

实际上我需要这个

- (void) changeColor:(???) myOBJ toColor:(UIColor*)myColor {
   myOBJ.color = myColor;
}
// what to put on ??? to make it generic? Is this a "whatever" kind?

感谢


修改

使用这种方法的问题

- (void) changeColor:(id)myOBJ toColor:(UIColor*)myColor {
   if ([myOBJ respondsToSelector:@selector(setColor:)]) {
       myOBJ.color = myColor;
   }
}

是这个。想象一下,我想设置对象的框架。 然后我将不得不这样做:

- (void) changeColor:(id)myOBJ newFrame:(CGRect)myFrame {

 if ([umID isKindOfClass:[Class1 class]]) {
   Class1 *oneObj = (Class1 *)myObj;
   oneObj.frame = myFrame;
 }

 if ([umID isKindOfClass:[Class2 class]]) 
   Class2 *oneObj = (Class2 *)myObj;
   oneObj.frame = myFrame;
 }


 if ([umID isKindOfClass:[Class3 class]]) 
   Class3 *oneObj = (Class3 *)myObj;
   oneObj.frame = myFrame;
 }

}
换句话说,我将不得不重复相同的东西3次......对吗?

换句话说,问题没有解决,因为这与3个方法相同,每个类一个。

5 个答案:

答案 0 :(得分:4)

也许你可以使用协议?使Class1,Class2和Class3符合具有属性myColor的协议。然后你可以有这样的方法(假设你的类是UIView类型,你的协议叫做ColorProtocol):

- (void) changeColor:(UIView<ColorProtocol>*) myOBJ toColor:(UIColor*)myColor {
   myOBJ.color = myColor;
   myOBJ.frame = ...;
}

以下是您的协议定义:

@protocol ColorProtocol

@property (nonatomic, retain) UIColor *myColor;

@end

按如下所示更改类定义文件(.h)以指定您将符合协议:

interface Class1 : UIView <ColorProtocol> {...}

在实现文件(.m)中,您必须简单地合成myColor属性以符合ColorProtocol:

@synthesize myColor;

如果你的类非常相似,那么使用继承可能更简单。查看Philip Regan的回答。

答案 1 :(得分:3)

你有几个选择。最简单且“最危险”的方法是使用类型id。这将允许您传入任何对象,但在尝试设置之前,您需要测试它实际上是否具有color属性。

- (void) changeColor:(id)myOBJ toColor:(UIColor*)myColor {
   if ([myOBJ respondsToSelector:@selector(setColor:)]) {
       myOBJ.color = myColor;
   }
}

(也就是说,响应选择器检查,这种方法并不是那么危险,而且它比下一个想法更灵活。)

另一种方法是让所有对象都从具有color属性的共享基类继承。然后您的参数类型将是基类。这种方法可以被认为是“更安全”,因为编译器会检查您是否传递了正确类型的对象。这种方法还需要更多代码。

如果您想使用第一种方法,但设置的不是颜色,请适当调整respondsToSelector:来电。

- (void) changeFrame:(id)myOBJ newFrame:(CGRect)myFrame {
   if ([myOBJ respondsToSelector:@selector(setFrame:)]) {
       myOBJ.frame = myFrame;
   }
}

通常,如果您想知道某个对象是否支持propertyX,请使用[myOBJ respondsToSelector:@selector(setPropertyX:)]。如果传入的对象声明为id,则可以调用[myOBJ setPropertyX:newPropertyValue]myObj.propertyX = newPropertyValue

答案 2 :(得分:2)

如果您有多个共享特征的类,那么,如果可能的话,我建议重构类结构,以便这些特性包含在伞形父类中,我们将其称为ClassZClassZ的子类可以根据需要覆盖事物。否则,让父类中的方法为您处理它。然后,你的方法又回到了这个......

- (void) changeColor:(ClassZ *) myOBJ toColor:(UIColor*)myColor {
   myOBJ.color = myColor; // note, myObj is ClassZ, not the subclasses.
}

否则,您将遇到id并测试各个类。

答案 3 :(得分:1)

使用[object setFrame:newFrame];代替object.frame = newFrame;
而不是oldFrame = object.frame;使用oldFrame = [object frame];

答案 4 :(得分:0)

???将是'id'。