How to remove one-time class variables from Objective-C code?

I write Objective-C code, and I often come across a situation where I need to use a class variable to store a value for one-time use. After that, I no longer need. For me, storing this value in a class variable is like the smell of code. Indeed, the value should be passed as a parameter to the methods that I use.

I usually come across this when I use delegates. As an example, I have a user interface with several buttons that are used to load and display the UIActionSheet when they are used. This action sheet contains a date picker that sets a value for UILabel when the action sheet is rejected.

 - (IBAction)setPurchaseDateTapped { self.activeField = purchaseDate; [self loadDatePickerActionSheet:@"Edit Purchase Date"]; } - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { self.activeField.text = value_from_UIActionSheet; } 

As you can see here, the actionSheetButtonAtIndex callback does not allow activeField to be activeField , so I need to use a class variable. It seems more correct to write this:

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

I believe (?) That I can subclass the UIActionSheet and UIActionSheet delegate and add the signatures I need, but again this seems like a lot of effort than it costs.

So my question is the best way to do what I'm trying to do?

I don't necessarily want to change the date / action selector interface I created (although if there is a better template for setting multiple dates in a UIView, keeping the DatePicker aside, I’m all ears.)

+6
objective-c iphone delegates uiactionsheet
source share
3 answers

In this case, I think that a simple subclass of UIActionSheet would be the path:

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

That should be enough, since all you want to do is have an actionSheet parameter. Your code may now look like this:

 - (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; } 
+3
source share

My usual approach in these situations is to use the tag property in UIAlertViews and include it (this is an integer). This is not as good as having a string or something to convey, but if you have a few warnings, this is an easy way to resolve the differences. For example:

 ... 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]; } 
+2
source share

Another solution is to use associative storage.

UIActionSheet may already have it. You can check it out on

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

Associative storage is pretty elegant if not overused.

+2
source share

All Articles