I have a custom button class:
CustomButton.h file:
@interface CustomButton : UIButton
@property (nonatomic, retain) NSString* info;
@end
CustomButton.m file:
#import "CustomButton.h"
@implementation CustomButton
@synthesize info;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
@end
In my main view controller:
CustomButton* btn = [CustomButton buttonWithType:UIButtonTypeDetailDisclosure];
[btn setInfo:@"foobar"];
NSLog(@"%@", [btn info]);
[self.view addSubview:btn];
If it’s just a simple button ([CustomButton new]) I don’t get any error. But if I choose buttonWithType:UIButtonTypeDetailDisclosure I get this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UIButton setInfo:]: unrecognized selector sent to instance 0x753c8c0'
Why is this happening?
As soon as
UIButtondoes not provideinitWithType:method – you can’t subclass a "typed" button. You can’t create an extension for a library class either.The only way to "attach" something to a predefined object is to use associated objects:
The "info" can be any string you like, it’s just a key to retrieve that object later.
OBJC_ASSOCIATION_RETAIN means that the object would be retained and automatically released after the
btnobject’sdealloc:would be called. You can find more details about that here.The other way to solve your issue is to subclass the UIButton, add your info property and make it look like disclosure button by setting custom image with
setImage:forState:method.Generally, coupling some data with standard UI controls is a sign of a bad architecture. Maybe you’ll make a little step backwards and try to find some other way to pass that string wherether you need to use it?