Loading a UITableView From A Nib
I keep getting a crash when loading a UITableView. I am trying to use a cell defined in a nib file.
I have an IBOutlet defined in the view controller header file:
UITableViewCell *jobCell;
@property (nonatomic, assign) IBOutlet UITableViewCell *jobCell;
This is synthesised in the implementation file.
I have a UITableViewCell created in IB and set it's identifier to JobCell.
Here is the cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"JobCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"JobsRootViewController" owner:self options:nil];
cell = jobCell;
self.jobCell = nil;
}
// Get this job
Job *job = [fetchedResultsController objectAtIndexPath:indexPath];
// Job title
UILabel *jobTitle;
jobTitle = (UILabel *)[cell viewWithTag:tagJobTitle];
jobTitle.text = job.title;
// Job due date
UILabel *dueDate;
dueDate = (UILabel *)[cell viewWithTag:tagJobDueDate];
dueDate.text = [self.dateFormatter stringFromDate:job.due开发者_开发技巧Date];
// Notes icon
UIImageView *notesImageView;
notesImageView = (UIImageView *)[cell viewWithTag:tagNotesImageView];
if ([job.notes length] > 0) {
// This job has a note attached to it - show the notes icon
notesImageView.hidden = NO;
}
else {
// Hide the notes icon
notesImageView.hidden = YES;
}
// Job completed button
// Return the cell
return cell;
}
When I run the app - I get a hard crash and the console reports the following:
objc[1291]: FREED(id): message style sent to freed object=0x4046400
I have hooked up all the outlets in IB correctly. What is the issue?
Thanks,
The easiest way to do this is to break it up into two separate nib files and load the cell from the cell's own nib. Something to note is that you cannot set outlets like this, if you want to do that, you will need a custom UITableViewCell subclass. But if you are not wiring up anything in the cell, you can simply do this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:@"JobsRootViewCell" owner:nil options:nil] objectAtIndex:0];
}
Your problem is in this block:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"JobsRootViewController" owner:self options:nil];
cell = jobCell; <- THIS IS A SHALLOW COPY
self.jobCell = nil; <- YOU JUST RELEASED IT
}
// Get this job
Job *job = [fetchedResultsController objectAtIndexPath:indexPath];
// Job title
UILabel *jobTitle;
jobTitle = (UILabel *)[cell viewWithTag:tagJobTitle]; <- CELL ISNT THERE ANYMORE
You're creating jobCell as an assigned property. The synthesized setter that you use when you say self.jobCell = nil releases the object that you just made cell reference. Make a deep copy instead, or don't set jobCell to nil.
Swift 3
- Cell
You should register your xib file in order to use it in tableView:
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerNib(UINib(nibName: "CellXibName", bundle: nil), forCellReuseIdentifier: "CellReuseIdentifier")
}
UITebleViewDataSource method:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellReuseIdentifier", forIndexPath: indexPath) as! CellClass
return cell
}
TableView
if let tableView: CustomTableView = nib?.first as? CustomTableView
{
self.view.addSubview(tableView)
}
精彩评论