3

I have a class with several similar properties - UISliders, and I'd like to add actions for when a user starts and ends using each slider. Each slider will be linked to the same selector, so I was thinking of just iterating over them instead of writing out 10 nearly identical blocks of code.

Question is, what's the most efficient way to do that? I tried something like this: Loop through all object properties at runtime but the problem is that I cannot call addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents on the objc_property_t property. Should I just stick the properties in an array and iterate over that?

Community
  • 1
  • 1
SaltyNuts
  • 5,068
  • 8
  • 48
  • 80

1 Answers1

4

If you don't require the level of dynamism that involves inspecting the properties of your object at run time, then an NSArray is the most straightforward and readable way; as far as efficiency I guess make a dynamic array of type void * and iterate through that would be maybe faster, but more work for you at a questionable speed payoff considering typical sizes.

for (UISlider *slider in @[self.slider1, self.slider2, self.slider3]) {
    [slider addTarget:self action:@selector(action:) forControlEvents:UIControlEventValueChanged];
}

If you do need to investigate your properties, then I'd approach it much as the answer on the other question suggested. My answer at first suggested parsing the property attribute string to account for custom named properties but apparently KVC takes care of that for you.

unsigned int numberOfProperties;
objc_property_t *properties = class_copyPropertyList([self class], &numberOfProperties);
for (int i = 0; i < numberOfProperties; i++) {
    objc_property_t property = propertieses[i];
    NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
    id valueForProperty = [self valueForKey:propertyName];
    if ([valueForProperty isKindOfClass:[UISlider class]]) {
        [(UISlider *)valueForProperty addTarget:self 
                                         action:@selector(action:) 
                               forControlEvents:UIControlEventValueChanged];
    }
}
free(properties);
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • The first answer is almost certainly what you want, although I'd just access the ivars directly (with ARC, I tend not to bother with properties at all). – tc. Jan 27 '13 at 01:09