Iphone 处理来自不同类的对象
我有3类对象。所有3个类共享一些共同的属性,如颜色、文本等 例如,我可以有这个Iphone 处理来自不同类的对象,iphone,objective-c,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.m
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个方法相同,每个类一个方法。???将是“id”。???将是“id”。您有几个选项。最简单也是最危险的方法是使用类型id。这将允许您传入任何对象,但您需要在尝试设置它之前测试它是否确实具有颜色属性
- (void) changeColor:(id)myOBJ toColor:(UIColor*)myColor {
if ([myOBJ respondsToSelector:@selector(setColor:)]) {
myOBJ.color = myColor;
}
}
这就是说,通过响应选择器检查,这种方法并不那么危险,而且比下一种方法灵活得多
另一种方法是让所有对象从具有颜色属性的共享基类继承。那么您的参数类型将是基类。这种方法可以被认为更安全,因为编译器会检查您是否传入了正确类型的对象。这种方法还需要相当多的代码
如果您想使用第一种方法,但设置了颜色以外的内容,请适当地调整respondsToSelector:call
- (void) changeFrame:(id)myOBJ newFrame:(CGRect)myFrame {
if ([myOBJ respondsToSelector:@selector(setFrame:)]) {
myOBJ.frame = myFrame;
}
}
通常,如果您想知道对象是否支持propertyX,请使用[myOBJ respondsToSelector:@selectorsetPropertyX:]。如果传入的对象声明为id,则可以调用[myOBJ setPropertyX:newPropertyValue]或myOBJ.propertyX=newPropertyValue。您有两个选项。最简单也是最危险的方法是使用类型id。这将允许您传入任何对象,但您需要在尝试设置它之前测试它是否确实具有颜色属性
- (void) changeColor:(id)myOBJ toColor:(UIColor*)myColor {
if ([myOBJ respondsToSelector:@selector(setColor:)]) {
myOBJ.color = myColor;
}
}
这就是说,通过响应选择器检查,这种方法并不那么危险,而且比下一种方法灵活得多
另一种方法是让所有对象从具有颜色属性的共享基类继承。那么您的参数类型将是基类。这种方法可以被认为更安全,因为编译器会检查您是否传入了正确类型的对象。这种方法还需要相当多的代码
如果您想使用第一种方法,但设置了颜色以外的内容,请适当地调整respondsToSelector:call
- (void) changeFrame:(id)myOBJ newFrame:(CGRect)myFrame {
if ([myOBJ respondsToSelector:@selector(setFrame:)]) {
myOBJ.frame = myFrame;
}
}
通常,如果您想知道对象是否支持propertyX,请使用[myOBJ respondsToSelector:@selectorsetPropertyX:]。如果传入的对象声明为id,则可以调用[myOBJ setPropertyX:newPropertyValue]或myOBJ.propertyX=newPropertyValue。也许可以使用协议?使Class1、Class2和Class3符合具有属性myColor的协议。然后,假设您的类是UIView类型,并且您的协议称为ColorProtocol,那么您可以有这样一个方法:
- (void) changeColor:(UIView<ColorProtocol>*) myOBJ toColor:(UIColor*)myColor {
myOBJ.color = myColor;
myOBJ.frame = ...;
}
@synthesize myColor;
按以下方式更改类定义文件.h,以指定您将遵守协议:
interface Class1 : UIView <ColorProtocol> {...}
如果您的类非常相似,那么使用继承可能更简单。看看Philip Regan的答案。也许你可以使用协议?使Class1、Class2和Class3符合具有属性myColor的协议。然后,假设您的类是UIView类型,并且您的协议称为ColorProtocol,那么您可以有这样一个方法:
- (void) changeColor:(UIView<ColorProtocol>*) myOBJ toColor:(UIColor*)myColor {
myOBJ.color = myColor;
myOBJ.frame = ...;
}
@synthesize myColor;
按以下方式更改类定义文件.h,以指定您将遵守协议:
interface Class1 : UIView <ColorProtocol> {...}
如果您的类非常相似,那么使用继承可能更简单。查看Philip Regan的答案。使用[object setFrame:newFrame];而不是object.frame=newFrame;
而不是oldFrame=object.frame;使用oldFrame=[对象帧] 使用[object setFrame:newFrame];而不是object.frame=newFrame;
而不是oldFrame=object.frame;使用oldFrame=[对象帧] 如果您有多个共享特性的类,那么,如果可能的话,我建议重构类结构,以便将这些特性包含在一个伞形父类中,我们称之为ClassZ。ClassZ的子类可以根据需要重写某些内容。否则,让父类中的方法为您处理它。然后,你的方法又变成了这个
- (void) changeColor:(ClassZ *) myOBJ toColor:(UIColor*)myColor {
myOBJ.color = myColor; // note, myObj is ClassZ, not the subclasses.
}
否则,您将不得不使用id并测试单个类。如果您有多个共享特性的类,那么,如果可能的话,我建议重构类结构,以便将这些特性包含在一个伞形父类中,我们将其称为ClassZ。ClassZ的子类可以根据需要重写某些内容。否则,让父类中的方法为您处理它。那么,哟 你的方法又变成了这个
- (void) changeColor:(ClassZ *) myOBJ toColor:(UIColor*)myColor {
myOBJ.color = myColor; // note, myObj is ClassZ, not the subclasses.
}
否则,您将无法使用id并测试各个类。无,但点表示法无法处理id类型的对象。这就是为什么object.frame=foo会导致编译错误,但[object setFrame:foo]编译并运行时没有任何问题。无,但是点表示法不适用于id类型的对象。这就是为什么object.frame=foo会导致编译错误,但[object setFrame:foo]编译并运行时没有任何问题。