6

我正在编写一些 Objective-C 代码,并且经常遇到必须使用类变量来存储一个值以供一次性使用的情况。吃完以后就不用了。对我来说,将此值存储在类变量中似乎是代码异味。实际上,该值应该作为参数传递给我正在使用的方法。

我通常在消费代表时遇到这个问题。例如,我有一个带有多个按钮的 UI,用于UIActionSheet在点击它们时加载和显示 a。UILabel此操作表包含一个日期选择器,该选择器为关闭操作表时的a 设置一个值。

- (IBAction)setPurchaseDateTapped {
    self.activeField = purchaseDate;
    [self loadDatePickerActionSheet:@"Edit Purchase Date"];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    self.activeField.text = value_from_UIActionSheet;
}

正如您在此处看到的,actionSheet clickedButtonAtIndex 回调不允许我传递,activeField所以我必须使用类变量。写这个似乎更正确:

- (void)actionSheet:(UIActionSheet *)actionSheet parameterValue:(id)parameter {
    parameter.text = value_from_UIActionSheet;
}

我相信(?)我可以继承 UIActionSheet 和 UIActionSheet 委托并添加我需要的签名,但这似乎比它的价值更多。

所以我的问题是做我想做的最好的方法是什么?

我不一定要更改我创建的日期选择器/操作表界面(尽管如果有更好的模式可以在 UIView 上设置多个日期同时保持 DatePicker 不碍事,我会全力以赴。)

4

3 回答 3

3

在这种情况下,我认为一个简单的子类UIActionSheet将是要走的路:

@interface SpecialActionSheet : UIActionSheet
{
    id parameter;
}
@property (assign) id parameter;
@end

@implementation SpecialActionSheet
@synthesize parameter;
@end

这应该足够了,因为您要做的就是让 actionSheet 保留一个参数。现在,您的代码可能如下所示:

- (void)loadDatePickerActionSheet:(NSString *)caption forField:(UITextField *)field {
    //...
    datePickerActionSheet.parameter = field;
}

- (IBAction)setPurchaseDateTapped {
    [self loadDatePickerActionSheet:@"Edit Purchase Date" forField:purchaseDate];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    UITextField * field = ((SpecialActionSheet *)actionSheet).parameter;
    field.text = value_from_UIActionSheet;
}
于 2010-01-25T17:28:02.150 回答
2

在这些情况下,我通常的做法是使用 UIAlertViews 上的 tag 属性,并对其进行切换(它是一个整数)。它不如有一个字符串或其他东西要传递,但如果你有多个警报,这是一种消除歧义的简单方法。例如:

...
actionSheet.tag = [fields indexOfObject: self.activeField];
...        //fields is an NSArray of all the field objects I might have on the screen


- (void)actionSheet:(UIActionSheet *)actionSheet parameterValue:(id)parameter {
    [[field objectAtIndex: actionSheet.tag] setText: value_from_UIActionSheet];
}
于 2010-01-25T17:29:25.017 回答
2

另一种解决方案是使用关联存储。

UIActionSheet 可能已经有了它。您可以通过以下方式对其进行测试

[myActionSheet setValue:@"test value" forKey:@"testKey];
NSLog(@"%@",[myActionSheet valueForKey:@"testKey];

如果没有过度使用,关联存储是相当漂亮的。

于 2010-01-25T18:53:35.707 回答