如何从 Objective-C 代码中删除一次性使用的类变量?

Posted

技术标签:

【中文标题】如何从 Objective-C 代码中删除一次性使用的类变量?【英文标题】:How do you remove one-time-use class variables from Objective-C code? 【发布时间】:2010-01-25 16:39:48 【问题描述】:

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

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

- (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,我就是耳朵。)

【问题讨论】:

【参考方案1】:

在这种情况下,我认为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;

【讨论】:

【参考方案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];

【讨论】:

我不知道 tags 属性。我得调查一下。【参考方案3】:

另一种解决方案是use associative storage.

UIActionSheet 可能已经有了它。你可以测试一下

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

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

【讨论】:

以上是关于如何从 Objective-C 代码中删除一次性使用的类变量?的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C/iOS:如何从 CoreData 中的属性中删除“值”?

如何在objective-c的动画中使视图振动? [关闭]

如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同?

如何使 UIImage 在 Objective-c 的 Xcode 中工作

从目标成员中删除文件后构建失败

从 SuperView 中删除子视图的问题 - Objective-C