0

Im trying to make it so that every single UIControl in my application (UIButton, UISlider, etc) all have special extra properties that I add to them.

I tried to accomplish this by creating a UIControl Category and importing it where needed but I have issues.

Here is my code.

My setSpecialproperty method gets called but it seems to be getting called in an infinite loop until the app crashes.

Can you tell me what Im doing wrong or suggest a smarter way to add a property to all of my UIControls?

@interface UIControl (MyControl)
{

}
@property(nonatomic,strong) MySpecialProperty  *specialproperty;

-(void)setSpecialproperty:(MySpecialProperty*)param;
@end

////////

#import "UIControl+MyControl.h"

@implementation UIControl (MyControl)

-(void)setSpecialproperty:(MySpecialProperty*)param
{
    self.specialproperty=param;
}

///////////////

#import "UIControl+MyControl.h"

@implementation ViewController


UIButton *abutton=[UIButton buttonWithType:UIButtonTypeCustom];
MySpecialProperty *prop=[MySpecialProperty alloc]init];
[abutton setSpecialproperty:prop];
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
dubbeat
  • 7,706
  • 18
  • 70
  • 122

4 Answers4

2

While you can't add an iVar to UIControl via a category, you can add Associated Objects, which can be used to perform much the same function.

So, create a category on UIControl like this:

static char kControlNameKey;

- (void) setControlName: (NSString *) name
{
    objc_setAssociatedObject(self, &kControlNameKey, name, OBJC_ASSOCIATION_COPY);
}

- (NSString *) controlName
{
    return (NSString *)objc_getAssociatedObject(array, &kControlNameKey);
}

There's more to it than that, I guess you'll need to check if an association exists before setting a new one, otherwise it will leak, but this should give you a start.

See the Apple Docs for more details

Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
1

self.specialproperty=param is exactly the same as calling [self setSpecialproperty] (see here for some totally non biased coverage of Obj-C dot notation), which makes your current usage infinitely recursive.

What you actually want to do is:

-(void)setSpecialproperty:(MySpecialProperty*)param
{
  _specialproperty = param;
}

Where _specialproperty is the implicitly created ivar for your property.

I'm assuming there's some reason why you've implemented your setSpecialproperty setter? Why not just use the one that is implicitly created for you?

sam-w
  • 7,478
  • 1
  • 47
  • 77
1

the problem is that you can not add a property to a category, you can add behavior (methods) but not properties or attributes, this can only be done to extensions, and you can not create extensions of the SDK classes

tkanzakic
  • 5,499
  • 16
  • 34
  • 41
  • So what Im trying to do is impossible? – dubbeat Feb 26 '13 at 12:44
  • the way you're trying to do it, yes it is not possible, @VineetSinghRawat give you an option, it could seems a bit complicated but it is not, just read it carefully – tkanzakic Feb 26 '13 at 12:51
  • 1
    this [article](http://www.cocoanetics.com/2012/06/associated-objects/) could be *more easy* to read than the Apple Doc – tkanzakic Feb 26 '13 at 12:53
-1

use your method as

change your method name to

-(void)setSpecialproperty:(MySpecialProperty *)specialproperty

-(void)setSpecialproperty:(MySpecialProperty*)specialproperty
{
   if(_specialproperty!=specialproperty)
  _specialproperty = specialproperty;
}

and synthesize your specialProperty as

@synthesize specialproperty=_specialproperty;
Prince Kumar Sharma
  • 12,591
  • 4
  • 59
  • 90
  • Synthesizing the property is not strictly necessary (since Xcode 4.4: http://stackoverflow.com/questions/12933785/ios-automatic-synthesize-without-creating-an-ivar) – sam-w Feb 26 '13 at 12:28