Search code examples
iosobjective-cnsstringnaming-conventionsdynamic-variables

Access Variable Dynamically


I have many buttons named like this:

@property (weak, nonatomic) IBOutlet UIButton *Round1Num1;
@property (weak, nonatomic) IBOutlet UIButton *Round1Num2;
@property (weak, nonatomic) IBOutlet UIButton *Round1Num3;
@property (weak, nonatomic) IBOutlet UIButton *Round1Num4;

@property (weak, nonatomic) IBOutlet UIButton *Round2Num1;
@property (weak, nonatomic) IBOutlet UIButton *Round2Num2;
@property (weak, nonatomic) IBOutlet UIButton *Round2Num3;
@property (weak, nonatomic) IBOutlet UIButton *Round2Num4;

and so on.

I was wondering if I could access them dynamically using stringWithFormat or a similar method.

Example (Sorry if the code is wrong!):

Instead of self.Round1Num1 I could call self.[NSString stringWithFormat:@"Round%dNum%d", 1, 1]


Solution

  • You could use -performSelector::

    NSString *round2Num1ButtonAccessorSelectorStr = [NSString stringWithFormat:@"Round%dNum%d", 2, 1];
    SEL selector = NSSelectorFromString(round2Num1ButtonAccessorSelectorStr);
    if ([self respondsToSelector:selector])
        UIButton *round2Num1Button = [self performSelector:selector];
    

    For context, [self performSelector:@selector(someSelector)] is essentially the equivalent to self.someSelector (in the case of a property accessor) which resolves to [self someSelector]. All cases actually call the same runtime function, objc_msgSend(self, someSelector).

    Specifically in this context, we're creating a local variable that points to the same reference concealed by the respective IBOutlet property on the VC instance. If the property doesn't exist, then neither will the selector (most likely) so you need to safeguard from an unrecognized selector exception via -respondsToSelector:.