I know there have been a ton of questions about the same thing, but so far I haven't been able to apply any solutions to my problem. And I still haven't figured out how to use Instruments.
I'm taking a basic tutorial for an iPhone app and just trying to tweak it slightly (I am new to Objective C). I want it to read from a plist with an array of dicts instead of an array of strings. The table initially displays the data correctly. However whenever I scroll the table up (and off the screen), I am getting Unrecognized Selector exceptions. Just populating employees with NSStrings works fine. I am lost.
Relevant portions of the ViewController:
@interface RootViewController : UITableViewController {
NSMutableArray *employees_;
}
@property (nonatomic, retain) NSMutableArray *employees;
@end
and
@implementation RootViewController
@synthesize employees=employees_;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Employees" ofType:@"plist"];
NSMutableArray *empArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
employees_ = [empArray valueForKey:@"name"];
[empArray release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [self.employees objectAtIndex:indexPath.row];//this is where it errors
return cell;
}
- (void)dealloc
{
[employees_ release];
[super dealloc];
}
@end
and plist:
array
dict
key name /key
string Employee One /string
key id /key
string T1234 /string
/dict
dict
key name /key
string Employee Two /string
key id /key
string T5678 /string
/dict
/array
Error that I received:
2011-10-18 20:02:44.313 MyApp[65148:bc03] -[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x689a050 2011-10-18 20:02:44.316 MyApp[65148:bc03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x689a050' *** Call stack at first throw: ( 0 CoreFoundation 0x00dc25a9 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x00f16313 objc_exception_throw + 44 2 CoreFoundation 0x00dc40bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 3 CoreFoundation 0x00d33966 ___forwarding___ + 966 4 CoreFoundation 0x00d33522 _CF_forwarding_prep_0 + 50 5 MyApp 0x00002a96 -[RootViewController tableView:cellForRowAtIndexPath:] + 326 6 UIKit 0x00089b98 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634 7 UIKit 0x0007f4cc -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75 8 UIKit 0x000948cc -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561 9 UIKit 0x0008c90c -[UITableView layoutSubviews] + 242 10 QuartzCore 0x016aca5a -[CALayer layoutSublayers] + 181 11 QuartzCore 0x016aeddc CALayerLayoutIfNeeded + 220 12 QuartzCore 0x016540b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310 13 QuartzCore 0x01655294 _ZN2CA11Transaction6commitEv + 292 14 QuartzCore 0x0165546d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99 15 CoreFoundation 0x00da389b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27 16 CoreFoundation 0x00d386e7 __CFRunLoopDoObservers + 295 17 CoreFoundation 0x00d011d7 __CFRunLoopRun + 1575 18 CoreFoundation 0x00d00840 CFRunLoopRunSpecific + 208 19 CoreFoundation 0x00d00761 CFRunLoopRunInMode + 97 20 GraphicsServices 0x00ffa1c4 GSEventRunModal + 217 21 GraphicsServices 0x00ffa289 GSEventRun + 115 22 UIKit 0x00022c93 UIApplicationMain + 1160 23 MyApp 0x00002249 main + 121 24 MyApp 0x000021c5 start + 53 ) terminate called throwing an exceptionCurrent language: auto; currently objective-c (gdb)
There are two potential problems:
You need to make sure the call to employees_ = [empArray valueForKey:@"name"]
is actually returning a NSArray
Once one is ruled out, and assuming you are not using ARC, your employees_ ivar is getting released before the table view gets a chance to configure itself. Try
employees_ = [[empArray valueForKey:@"name"] retain];
And then release employees_ in your viewDidUnload & dealloc methods.
Hard to tell it from the stack as it does say your ivar is a NSCFString but it could be just because it is referencing an invalid/garbage memory address. Based on your plist description though, the likely cause on on point #1.
-[NSCFString objectAtIndex:]: unrecognized selector
This means you tried to send the selector (i.e. call the method) objectAtIndex:
on an instance of class NSCFString
(which is the same as NSString). ("Next Step / Core Foundation String")
You can't do that.
Since you only are calling objectAtIndex: in one place in your above code, it's easy to see where the problem is. (Besides which in your debugger you should be able to see what line it happens on.) You're calling [self.employees objectAtIndex:...]
. Obviously you expect self.employees to be an array, but it is a string instead. I don't really know about plist processing, so figuring out why employees got a string and how to make it get an array instead is up to you.
User contributions licensed under CC BY-SA 3.0