Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use arguments as variable names in objective-c

I'm new at objective-c and stuck with a problem. Is it possible to take an argument of a function to use as some variable names?

For example, say I have a bunch of image: aPic1, aPic2, bPic1, bPic2, cPic1, cPic2, and I want to create an action so that every time when a button is clicked, the view controller will hide Pic1 and display Pic2, depending which button is clicked.

- (void) performAction:(NSMutableString *) text
{
    [text appendString:@"Pic1"].hidden = YES;    //I wanna hide textPic1, which is a UIImageView
    [text appendString:@"Pic2"].hidden = NO;     //I wanna show textPic2, which is also a UIImageView
}

I know I should not use NSString or NSMutableString in this case. Anyone has any idea how I can achieve my objective with this kind of function? Thanks.

like image 202
Anthony Avatar asked Jan 23 '23 17:01

Anthony


2 Answers

Yes you can. (c) :)

For the solution I suggest to work you will need to be able to access (set/get) your variables via methods (easily done using properties or writing your own setters and getters).

Here's an example:

- (void)performAction:(NSMutableString *)text {
    [(UIImageView *)[self performSelector:NSSelectorFromString([text stringByAppendingString:@"Pic1"])] setHidden:YES];
    [(UIImageView *)[self performSelector:NSSelectorFromString([text stringByAppendingString:@"Pic2"])] setHidden:NO];
}

As for properties I actually thought about simply giving you a sample code to get start using this great feature of Objective-C ASAP, which I will do. Though I'm not sure about going deep into this topic because it may require too much of Internet paper, so that's why after the sample code I'll also add a few links for further reading.

@interface AClass : NSObject {
    // Here's where you declare variables
    NSObject *objectForInternalUseWeWantToBeRetained;
    id linkToObjectUsuallyNotRetained;
    int nonObjectVariable;
    BOOL aVariableWithARenamedGetter;
}

// And here's where their properties are declared
@property (nonatomic, retain) NSObject *objectForInternalUseWeWantToBeRetained;
@property (nonatomic) id linkToObjectUsuallyNotRetained;
@property (nonatomic, assign) int nonObjectVariable;
@property (nonatomic, assign, getter=renamedVariableGetter) BOOL aVariableWithARenamedGetter;


@end


@implementation AClass

// Here we command the machine to generate getters/setters for these properties automagically
@synthesize objectForInternalUseWeWantToBeRetained, linkToObjectUsuallyNotRetained, nonObjectVariable, aVariableWithARenamedGetter;

// But you can implement any of the getters/setters by yourself to add some additional behaviour
- (NSObject *)objectForInternalUseWeWantToBeRetained {
    // Some additional non-usual stuff here

    // And after that we do the getters job - return the variables value
    return objectForInternalUseWeWantToBeRetained;
}

// And of course we don't forget to release all the objects we retained on dealloc
- (void)dealloc {
    [objectForInternalUseWeWantToBeRetained release];

    [super dealloc];
}


@end

// And here's where their properties are declared
@property (nonatomic, retain) UIImageView *testPic1;
@property (nonatomic, retain) UIImageView *testPic2;


@end

Warning: I ran through the suff very quickly. Here's a nice tutorial at CocoaCast blog - Properties in Objective-C 2.0, which I think might be a good starting point. BTW they provide a lot of learning materials (podcasts, screencasts, etc) so browsing their site further might be useful. And of course the main place to learn all about Objective-C and Cocoa is official documentation, here's where it is about properties.

like image 62
Ivan Karpan Avatar answered Jan 31 '23 19:01

Ivan Karpan


This is possible, but in a roundabout way. You can make the ivars @properties on your class, and then access them via:

id myIvar = [self valueForKey:[text appendString:@"Pic1"]];
[myIvar setHidden:YES];

Or you can go lower in the runtime and use these methods:

#import <objc/runtime.h>

id myIvarValue = nil;
[text appendString:@"Pic1"];
Ivar theIvar = object_getInstanceVariable(self, [text UTF8String], &myIvarValue];
[myIvarValue setHidden:YES];
like image 38
Dave DeLong Avatar answered Jan 31 '23 19:01

Dave DeLong