Unable to use my NSString object in my tableView
Sorry for the lack of detail in the title, but it's something I'll have to explain.
NSUInteger row = [indexPath row];
NSDictionary *selectedEvent = [list objectAtIndex:row];
NSString *eventTitle = [selectedEvent objectForKey:@"Title"];
NSString *detailMessage = [[NSString alloc] initWithFormat: @"You pressed the button for %@.", eventTitle];
childController.message = detailMessage;
childController.title = eventTitle;
The code gives me a reason: '-[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x6a19ee0'
What event title gives you is justpiece of text. I've used it in my data source methods but for some reason in the delegate it won't let me use it.
The following is how the dictionary is setup. Keep in mind it's just a snippet:
NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys: poster, @"Poster", @"The Addam's Family", @"Title", @"Dancap Productions", @"PresentedBy", @"The weird and wonderful family comes to devilishly delightful life in THE ADDAMS FAMILY.", @"Description", nil];
NSArray *array = [[NSArray alloc] initWithObjects: row1, nil];
self.list = array;
Edit:
Here is the full class. I'll need to know what I'm leaking if I am to learn!
#import <UIKit/UIKit.h>
#import "SecondLevelViewController.h"
@class EventsDetailController;
#define kPosterValueTag 1
#define kTitleValueTag 2
#define kPresentedValueTag 3
#define kDescriptionValueTag 4
@interface EventsButtonController : SecondLevelViewController {
NSArray *list; //array holding all of the events
EventsDetailController *childController;
NSString *theatreType;
}
@property (nonatomic, retain) NSArray *list;
@property (nonatomic, retain) NSString *theatreType;
@end
#import "EventsButtonController.h"
#import "TCA_BaseAppDelegate.h";
#import "EventsDetailController.h";
@implementation EventsButtonController
@synthesize list;
@synthesize theatreType;
-(void)viewDidLoad{
//table heading
UIView *containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 360, 60)] autorelease];
UILabel *headerLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 360, 60)] autorelease];
headerLabel.text = NSLocalizedString(@"Header for the table", @"");
headerLabel.textColor = [UIColor blackColor];
headerLabel.shadowColor = [UIColor blackColor];
headerLabel.shadowOffset = CGSizeMake(0, 1);
headerLabel.font = [UIFont boldSystemFontOfSize:22];
headerLabel.backgroundColor = [UIColor redColor];
[containerView addSubview:headerLabel];
self.tableView.tableHeaderView = containerView;
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
//end table heading
//poster image
UIImage *poster = [UIImage imageNamed:@"test_poster.png"];
NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys: poster, @"Poster", @"The Addam's Family", @"Title", @"Dancap Productions", @"PresentedBy", @"The weird and wonderful family comes to devilishly delightful life in THE ADDAMS FAMILY.", @"Description", nil];
NSArray *array = [[NSArray alloc] initWithObjects: row1, nil];
self.list = array;
[row1 release];
[array release];
[super viewDidLoad];
}
-(void)viewDidUnload{
self.list = nil;
[childController release], childController = nil;
}
-(void)dealloc{
[list release];
[childController release];
[super dealloc];
}
#pragma mark -
#pragma mark Table Data Source Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [list count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *DisclosureButtonCellIdentifier = @"DisclosureButtonCellIdentifier"; //set identifier for the cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: DisclosureButtonCellIdentifier]; //set the identifier for dequeue ie. cells hidden from the screen
NSUInteger row = [indexPath row]; //put this stuff first so we can retrieve the size of the text
NSDictionary *rowData = [list objectAtIndex:row];
if(cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier] autorelease];
//start adding custom subviews to the table cell
//add subview for the poster
UIImageView *posterValue = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,105,175)];
posterValue.tag = kPosterValueTag;
[cell.contentView addSubview:posterValue];
[posterValue release];
//addsubview for the Title
UILabel *titleValue = [[UILabel alloc] initWithFrame:CGRectMake(125,10,185,30)];
titleValue.tag = kTitleValueTag;
titleValue.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:titleValue];
[titleValue release];
//addSubview for the PresentedBy
UILabel *presentedValue = [[UILabel alloc] initWithFrame:CGRectMake(125,30,185,30)];
presentedValue.tag = kPresentedValueTag;
presentedValue.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:presentedValue];
[presentedValue release];
//addSubview for Description
UILabel *descValue = [[UILabel alloc] init];
NSString *descString = [rowData objectForKey:@"Description"];
CGSize maximumSize = CGSizeMake(185, 140);
UIFont *descFont = [UIFont fontWithName:@"Helvetica" size:12];
CGSize descStringSize = [descString sizeWithFont:descFont
constrainedToSize:maximumSize
lineBreakMode:descValue.lineBreakMode];
CGRect descFrame = CGRectMake(125, 60, 185, descStringSize.height);
descValue.frame = descFrame;
//descValue.backgroundColor = [UIColor redColor];
descValue.font = descFont;
descValue.tag = kDescriptionValueTag;
descValue.lineBreakMode = UILineBreakModeWordWrap;
descValue.numberOfLines = 0;
[cell.contentView addSubview:descValue];
[descValue release];
}
//add content
UIImageView *poster = (UIImageView *)[cell.contentView viewWithTag:kPosterValueTag];
poster.image = [rowData objectForKey:@"Poster"];
UILabel *title = (UILabel *)[cell.contentView viewWithTag:kTitleValueTag];
title.text = [rowData objectForKey:@"Title"];
UILabel *presented = (UILabel *)[cell.contentView viewWithTag:kPresentedValueTag];
presented.text = [rowData objectForKey:@"PresentedBy"];
UILabel *desc = (UILabel *)[cell.contentView viewWithTag:kDescriptionValueTag];
desc.text = [rowData objectForKey:@"Description"];
//add accessoryType for chevron icon.
[cell setSelectionStyle:UITableViewCellSelectionStyleNone]; //disables the blue highlight when the cell is selected
[rowData release];
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//makes the next drill down's button have the label of "back"
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: @"back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton releas开发者_JS百科e];
if(childController == nil){
childController = [[EventsDetailController alloc] initWithNibName: @"EventsDetail" bundle:nil];
}
childController.title = @"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSDictionary *selectedEvent = [list objectAtIndex:row];
NSString *eventTitle = [selectedEvent objectForKey:@"Title"];
NSString *detailMessage = [[NSString alloc] initWithFormat: @"You pressed the disclosure button for %@.", eventTitle];
childController.message = detailMessage;
childController.title = eventTitle;
[detailMessage release];
[self.navigationController pushViewController:childController animated:YES];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 195;
}
@end
I dont know if I'm right, but in the Data Source method when I utilize the Dictionary objects within the list array I assigned them to rowData and then I released them. Am I releasing the actual dictionary object and not a instance of them? Therefore, I am left with nothing in the list array? If that's the case do I not release them ever?
properly deallocate objects when you no longer own them.
What is list? Is it retain or assign more detail is needed.
The error says that your calling a method in an object that doesn't recognize it so it may mean you accidently released the object and your calling a method on garbage memory.
Insert this line between 2nd and 3rd line of first piece of your code,
if ([list isKindOfClass:[NSDictionary class]] {
NSLog(@"It's NSDictonary");
}
to make sure you actually got list
as a NSDictionary
.
ISTM that it could be that, when you access list
after initializing the childController
, viewDidLoad
might not have run yet (on self
), and in that case, list
is still nil
.
Since invoking methods on nil
is simply handled silently, you don't get a runtime error yet. But your selectedEvent
variable still contains garbage. Now, if you call [selectedEvent objectForKey: row]
, you call that on garbage, and that probably causes the runtime error.
Try a few things:
Use NSLog
Add an NSLog entry in viewDidLoad to indicate the routine was called:
NSLog(@"viewDidLoad")
check if
list
is notnil
before you access it. UseNSLog(@"self.list: %@", self.list);
check
selectedEvent
:NSLog(@"selectedEvent: %@", selectedEvent);
That will show you what happens. If necessary, add more NSLog entries.
Debug
Put a breakpoint on the line where you access self.list
and in ViewDidLoad
. Inspect the variables, single step the code, etc. This should give you more insight in what might be happening.
We can't see such things, from here. ;-)
精彩评论