Reputation: 785
I'm trying to break some of my "super objects" into more manageable classes that have single (or at least limited) responsibility.
One problem I've just run into is making an object of a specific instance of a UIBarButtonItem. In the class it is in now I first define a UIButton, and then all of the images that act as icons for that button as subviews (for instance the button represents access/control to a device, and I use the button image to show the current signal strength of that device). Also that button is listening for NSNotifications from the device object to represent the signal strength changing, or if the device disconnects. And pressing the button sends a message to the device to disconnect. All of this code works perfectly fine now as a property of the RootViewController. However, I want to pull it out into its own class as the button is shared by several classes, and it just clutters up the controller with unnecessary methods.
I tried making an separate class with an init like below. However, this doesn't work as the self used for the button isn't the same self that is ultimately created by [UIBarButtonItem alloc] and when either the NSNotification or the button press try to send a message to the selector of "self", that object has already been dealloced. The problem is, I'm not sure how to create a object (as defined by the class) that is just an instance of another class, as opposed to a property of an object (as it currently is for the RootViewController).
Edit and additional explanation of my problem
MyClass is currently subclass of UIBarButtonItem. However, I'm not trying to use it like this: [[MyClass alloc] initWithCustomView:]. I want [MyClass alloc] init] by itself to completely create the custom view - in other words the whole point of this class is to completely contain all that is necessary for this button to create itself, manage its subviews, and take the appropriate action when it is pressed. (I could easily make MyClass an NSObject with a public method like [MyClass setupButton] and a public property of type UIBarButtonItem. However, I think that looks wrong because then the class is only there to create the button, but it is not the button itself.)
@interface MyClass : UIBarButtonItem
@end
@implementation MyClass
- (id)init {
if (self = [super init]) {
UIImage *defaultButton = [[UIImage imageNamed:@"...
UIImage *defaultButtonPressed = [[UIImage imageNamed:@"....
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 30)];
[button setBackgroundImage:defaultButton forState:UIControlStateNormal];
[button setBackgroundImage:defaultButtonPressed forState:UIControlStateHighlighted];
[button addTarget:self action:@selector(deviceButtonPressed) forControlEvents:UIControlEventTouchUpInside];
//Then several UIImageViews that are added as subviews of the button, initially hidden
//Then set up the NSNotification listener
//Finally
self = [[UIBarButtonItem alloc] initWithCustomView:button];
}
return self;
}
//Then several functions to handle hiding and unhiding the subviews depending on the received device notifications, and a function to handle the button press and sending the message back to the device.
Upvotes: 0
Views: 133
Reputation: 64002
This is not how initialization works in Cocoa. Please read "Initialization" in the Cocoa Core Competencies guide.
Your object has already been allocated when this init
method is run. You should not be reassigning the self
pointer to another allocation.
Your class should first call its superclass's designated initializer self = [super initWithWhatever:obj];
, then set up its own properties.
Upvotes: 1
Reputation: 43842
It seems to me that you want to extend UIBarButtonItem
, not create an instance of it in your init
method. Try changing your class declaration (in your class's .h file) from this:
@interface MyClass : NSObject
to this:
@interface MyClass : UIBarButtonItem
Then just return self
in your init
method. Setting self
to a value is usually a bad idea.
If you're unsure about what's going on here, you're creating a subclass of UIBarButtonItem. This lets your subclass extend the superclass's functionality. If you're confused, you should take a look at subclassing/class inheritance in object-oriented languages to understand what's going on. This guide documents how classes work in Objective-C.
Upvotes: 1