Reputation: 1431
I'm noob in ObjC, I'm trying to understand some basic concept that seems to be confused also in the thousands of tutorial in the web. My problem is with the management of the file's owner. For example, if I want a custom cell in a UITableView
object, I need:
1) to make, in Interface Builder, a NIB file with my custom cell
2) create my `CustomCellControllerClass` and set is as Custom Class
in the Identity Inspector;
3) in my `CustomCellControllerClass` add the IBOutlet property
4) connect every item in my NIB file with respective Outlet
So, I have in my connection inspector something like this
item --- File's Owner
Now, begin problems: between all methods proposed, the most "clean" to me seems to be initializing my custom cell in init
method in my CustomCellControllerClass
; something like this:
-(id) init
{
self=[super init];
self=[[[NSBundle mainBundle]
loadNibName:@"CustomCellNib"
owner: self options:nil] lastObject];
return self;
}
Now, when I start the program all seems ok, but...I can't control the Outlets!
I think because I set as Owner an old instance of the self
object, loadNibName:Owner:options:
returns a new object with owner the old self
object. So, the bind between Outlets is made with the old self object.
I would that my loaded Nib has owner itself (loadNibName:Owner:options:
return CustomCellControllerClass objects, so could not be strange set it as owner of itself), but seems it's not possible.. All this seems to me terribly recursive!
The way I found to partially "resolve" the problems is the follow:
-(id) init
{
self=[super init];
CustomCellControllerClass* ccp=[[[NSBundle mainBundle]
loadNibName:@"CustomCellNib"
owner: self options:nil] lastObject];
[self addSubView:ccp];
return self;
}
so, I don't lose my original self
reference and I can handle my property.
The problem is that now my CustomCell is just a subview, with all the problems of the case, I would to make it the "main" view.
Is my reasoning right? Where I wrong? How could resolve these problems in a better way?
Upvotes: 0
Views: 91
Reputation: 42598
Registering the NIB with the table view is the correct way to handle this.
To answer your question directly, reassigning self
to the first result of -loadNibName:owner:options:
is a total kludge! But… sometimes a kludge is what's needed.
As a side note, don't pass self
as the owner, pass nil
, and use a class method for the NIB name, it will make subclassing easier.
- (instancetype)init
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *name = [[self class] nibName];
self = [bundle loadNibName:name owner:nil options:nil].firstObject;
return self;
}
+ (NSString *)nibName
{
return @"CustomCellNib";
}
Here is an updated regarding using self
as the owner. In the code sample, you passed self
as the owner, then reassigned self
to a new object.
-(id) init
{
/* old self */self=[super init];
/* NIB object */self=[[[NSBundle mainBundle]
loadNibName:@"CustomCellNib"
owner: /* old self */self options:nil] lastObject];
return /* NIB object */self;
}
As you can see, the owner is the old self, but the returned value is the NIB object. Anything assigned to the owner in the NIB will be assigned to the old self and is lost.
The solution is to never use the owner in the NIB when you have this kind of setup, any outlets you need to setup must be established to the NIB object.
Upvotes: 1