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.
Related
I define my array in my AppDelegate.h like this:
NSMutableArray *myWishesArray;
.
.
#property (nonatomic, retain) NSMutableArray *myWishesArray;
In AppDelegate.m, i allocate its object like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myWishesArray = [[NSMutableArray alloc] init];
.
.
return YES;
}
Suppose i have a function "Add Data to array", like this:
-(void)addDataToArray
{
NSMutableArray *tempArray = //Gets data from a web service
if ([tempArray count] > 0) {
[objAppDelegate.myWishesArray addObjectsFromArray:tempArray];
[self.myWishesTableView reloadData];
}
}
In viewDidLoad of MyViewController.m, I load the first set of 8 records into my array:
- (void)viewDidLoad {
[self addDataToArray]; //fetches page number 1 of the data to be fetched
}
In scrollViewDidEndDragging of MyViewController.m, i add next set of 8 records and use the same above mentioned code to add it in the objAppDelegate.myWishesArray:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
currentPageNumber++;
[self addDataToArray]; //fetches data for next page number
}
-(void)viewWillAppear:(BOOL)animated
{
[self.myWishesTableView reloadData];
}
This is my cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *myArrayObject = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
}
Every time i try to click a row of the table which was visible in my table view, but was just at the end of being loaded, my app gets crashed with the following exception. It may be initial loading or loading more rows as a result of scrolling down the table view. Please keep in mind that when i give the table view enough time to settle and the motion stops and data is fully loaded, then i dont face any exception on clicking the loaded rows.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x013a8be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x014fd5c2 objc_exception_throw + 47
2 CoreFoundation 0x0139e80c -[__NSArrayI objectAtIndex:] + 236
3 WishHaHa 0x00004e1a -[AsyncImageView image] + 66
4 UIKit 0x0044e56b -[UIImageView setBackgroundColor:] + 101
5 UIKit 0x00549448 -[UITableViewCell _setOpaque:forSubview:] + 953
6 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
7 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
8 UIKit 0x0054472d -[UITableViewCell(UITableViewCellStatic) _updateAndCacheBackgroundColorForHighlightIgnoringSelection:] + 117
9 UIKit 0x0054c12a -[UITableViewCell showSelectedBackgroundView:animated:] + 1435
10 UIKit 0x00548ce3 -[UITableViewCell setHighlighted:animated:] + 231
11 UIKit 0x003fbd3b -[UITableView highlightRowAtIndexPath:animated:scrollPosition:] + 756
12 UIKit 0x003f78d8 -[UITableView touchesBegan:withEvent:] + 1349
13 UIKit 0x004512b8 forwardMethod2 + 92
14 UIKit 0x0054cc15 -[UITableViewCell touchesBegan:withEvent:] + 319
15 UIKit 0x004512b8 forwardMethod2 + 92
16 UIKit 0x00610987 _UIGestureRecognizerSortAndSendDelayedTouches + 3609
17 UIKit 0x006110fc _UIGestureRecognizerUpdateObserver + 927
18 CoreFoundation 0x01389fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
19 CoreFoundation 0x0131f0e7 __CFRunLoopDoObservers + 295
20 CoreFoundation 0x012e7bd7 __CFRunLoopRun + 1575
21 CoreFoundation 0x012e7240 CFRunLoopRunSpecific + 208
22 CoreFoundation 0x012e7161 CFRunLoopRunInMode + 97
23 GraphicsServices 0x01a9d268 GSEventRunModal + 217
24 GraphicsServices 0x01a9d32d GSEventRun + 115
25 UIKit 0x0039442e UIApplicationMain + 1160
26 WishHaHa 0x00002a5c main + 102
27 WishHaHa 0x000029ed start + 53
)
terminate called after throwing an instance of 'NSException'
I have done a lot of research on my problem and found that possible causes of NSRangeException may be:
numberOfRowsInSection:(NSInteger)section; method of the UITableView's
data source is delivering wrong values.
retain should be called on the array.
Whenever you modify the underlying data for a table view you need to
update the changes by either calling -[UITableView reloadData]; or
the beginUpdates and endUpdates methods then adding or removing the
correct index paths.
I dont think that my code has first issue. If there is second issue, then where should i make the call to retain myWishesArray? If there is third issue with my code, then how should i proceed to change my code?
Please let me know where i am doing anything wrong. I am stuck on this issue since really long.
Thanks
Edit:
After thorough investigation of the code, i have found the point which is causing this error. I am asynchronously downloading the images in cells of my table view, using the asyncimageview class. Let me paste some code here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomWishCell";
CustomWishCell *cell = (CustomWishCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomWishCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomWishCell *) currentObject;
break;
}
}
}
else
{
AsyncImageView* oldImage = (AsyncImageView*)[cell.contentView viewWithTag:999];
[oldImage removeFromSuperview];
}
if (indexPath.row<[objAppDelegate.myWishesArray count]) {
Wish *objWish = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
NSString *test = objWish.facebookUserId;
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
cell.wishLabel.attributedText = [self.myEngine makeWisherNameAndContents:objWish.firstName lastName:objWish.lastName wishContents:objWish.contents];
}
return cell;
}
Now, myEngine contains the definitioin:
-(void)loadAsynchronousImageURLInView:(NSString*)imageUrl imageView:(UIView*)targetView
{
CGRect frame;
frame.size.width=45;
frame.size.height=45;
frame.origin.x=0;
frame.origin.y=0;
if (imageUrl != (id)[NSNull null] )
{
AsyncImageView* asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
asyncImage.tag = 999;
NSURL *url = [NSURL URLWithString:imageUrl];
[asyncImage loadImageFromURL:url];
[targetView addSubview:asyncImage];
}
}
And the AsyncImageView class loads the image using NSURLConnection class.
Please note that the app works all ok when i comment this line defined in cellForRowAtIndexPath method:
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
It does not crash when i click on any row that was loading. Please let me know how should i change my logic. I am not allowed to load the images synchronously, or show any indicator while images are downloading.
Your array with which you are loading your tableview is either not getting filled or is getting released somewhere before you tap on the tableView.
Please add the code where you release your array and Also please make sure that you are synthesizing your array in AppDelegate.
I think there is some issue with the array and not the tableView as array is getting empty.
I hope this helps.
It sounds to me as if your addDataToArray method does not manage to retrieve the data and fill the myWishesArray array before the click is handled.
Are you retrieving the data from the web service asynchronously?
Is there any way to retrieve all the data at once instead of retrieving it by sections?
I am trying to implement a tab bar controller, navigation controller and tableview into an application I'm working on but I am getting a SIGABRT error each time I try to run it and I don't know why and it is rather puzzling me. Below is the code that the console is referencing to (I believe):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSString *cellValue = [listOfCoffees objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
...and below is the console:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x6a17c00'
*** Call stack at first throw:
(
0 CoreFoundation 0x00dca5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f1e313 objc_exception_throw + 44
2 CoreFoundation 0x00dcc0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00d3b966 ___forwarding___ + 966
4 CoreFoundation 0x00d3b522 _CF_forwarding_prep_0 + 50
5 UIKit 0x00091b98 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
6 UIKit 0x000874cc -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
7 UIKit 0x0009c8cc -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
8 UIKit 0x0009490c -[UITableView layoutSubviews] + 242
9 QuartzCore 0x016b4a5a -[CALayer layoutSublayers] + 181
10 QuartzCore 0x016b6ddc CALayerLayoutIfNeeded + 220
11 QuartzCore 0x0165c0b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
12 QuartzCore 0x0165d294 _ZN2CA11Transaction6commitEv + 292
13 QuartzCore 0x0165d46d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
14 CoreFoundation 0x00dab89b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
15 CoreFoundation 0x00d406e7 __CFRunLoopDoObservers + 295
16 CoreFoundation 0x00d091d7 __CFRunLoopRun + 1575
17 CoreFoundation 0x00d08840 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x00d08761 CFRunLoopRunInMode + 97
19 GraphicsServices 0x010021c4 GSEventRunModal + 217
20 GraphicsServices 0x01002289 GSEventRun + 115
21 UIKit 0x0002ac93 UIApplicationMain + 1160
22 Affogato 0x00002259 main + 121
23 Affogato 0x000021d5 start + 53
24 ??? 0x00000001 0x0 + 1
)
terminate called throwing an exception
Any help would be greatly appreciated.
I'm quite sure the actual problem is somewhere else in the code, my guess would be you are using some string variable (possibly selectedCoffee ?) in place of the tableView's delegate.
The error is in the tableview delegate/datasource. CellForRowAtIndexPath is called by the tableview to query it's UITableViewCell object. Check your delegate/datasource connection.
Set a breakpoint and look where the app crash. Then we could help more.
I have a problem here. Or Maybe I'm really tired...
I have a class :
#interface THECLASS : UIViewController <UITableViewDelegate> {
NSMutableArray* param;
}
#property(nonatomic, retain) NSMutableArray* param;
Inside that class I have a method that is called when the user clicks on a UISwitch inside a tableViewCell (I build the params into a IBAction method that is not shwon here) :
#synthesize param;
- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
[self.param addObject:#"eeeee"];
}
This crashes the app with the following log :
2011-02-04 01:31:02.548 Learning Project[3895:207] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x630c960
2011-02-04 01:31:02.549 Learning Project[3895:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x630c960'
*** Call stack at first throw:
(
0 CoreFoundation 0x00fc4be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x011195c2 objc_exception_throw + 47
2 CoreFoundation 0x00fc66fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00f36366 ___forwarding___ + 966
4 CoreFoundation 0x00f35f22 _CF_forwarding_prep_0 + 50
5 Learning Project 0x00019463 -[ChoixJoursDisponibiliteController changedSelectorValue:isOn:] + 644
6 Learning Project 0x000190db -[ChoixJoursDisponibiliteController clickChangedSelectorValue:] + 307
7 UIKit 0x002f6a6e -[UIApplication sendAction:to:from:forEvent:] + 119
8 UIKit 0x003851b5 -[UIControl sendAction:to:forEvent:] + 67
9 UIKit 0x00387647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
10 UIKit 0x004c9c6d -[UISwitch _onAnimationDidStop:finished:context:] + 201
11 UIKit 0x00327665 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 294
12 UIKit 0x003274f7 -[UIViewAnimationState animationDidStop:finished:] + 77
13 QuartzCore 0x01eab6cb _ZL23run_animation_callbacksdPv + 278
14 QuartzCore 0x01eab589 _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 157
15 CoreFoundation 0x00fa5fe3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
16 CoreFoundation 0x00fa7594 __CFRunLoopDoTimer + 1220
17 CoreFoundation 0x00f03cc9 __CFRunLoopRun + 1817
18 CoreFoundation 0x00f03240 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x00f03161 CFRunLoopRunInMode + 97
20 GraphicsServices 0x018f9268 GSEventRunModal + 217
21 GraphicsServices 0x018f932d GSEventRun + 115
22 UIKit 0x0030542e UIApplicationMain + 1160
23 Learning Project 0x00002580 main + 102
24 Learning Project 0x00002511 start + 53
25 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
param is filled from a caller view by something like :
NSMutableArray* filledArray = [NSMutableArray arrayWithObjects:#"SOME TEXT", nil]
nextController.param = filledArray;
NSLog(#"%#", self.param); just before the crash gives :
2011-02-04 02:01:17.205 Learning Project[4223:207] (
"JOURDISPO_MARDI"
)
Why does this crash ?
The array is there, filled and not nil... It seems well defined... addObject is a NSMutableArray method... I don't understand
I don't show it here but there is the same log with removeObject.
Answer is buried in the comments to the "accepted" answer. I came here from Google and it fixed my problem, so ... to make it clearer, based on #e.James's comment:
When you implement the "NSCopying" protocol, and implement
"copyWithZone", you MUST NOT use "copy" on your internal mutable arrays - this
DOES NOT copy the array (instead, it creates a non-mutable copy).
e.g. from my own code:
// Class: MyClass
#property(nonatomic, retain) NSMutableArray* mutArray;
-(id)copyWithZone:(NSZone *)zone
{
MyClass* other = [[MyClass alloc] init];
// other.mutArray = [self.mutArray copy]; // WRONG!
other.mutArray = [self.mutArray mutableCopy]; // CORRECT!
return other;
}
For some reason you're calling the addObject: method on an instance of NSArray, as the stack trace indicates. Perhaps the synthesized getter of your param object returns an NSArray? Don't use the getter in your method:
- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
[param addObject:#"eeeee"];
}
Ultimately, the error is correct. You're calling a mutating method on an immutable object. Strange enough, in my testing this doesn't cause a compiler error or warning:
NSMutableArray *array = [[NSArray alloc] init];
Edit: Whether you want to believe it or not, somehow the param ivar is being set to an instance of an NSArray. Override the setter:
- (void)setParam:(NSMutableArray *)p {
if (param != p) {
[param release];
param = [p retain];
}
}
Then add a breakpoint on that method, and check to see when an NSArray is being passed in.
Your property is defined as retain, and you say that param is "a filled array from the caller view". This could be your problem.
For example, if you do the following:
NSArray * filledArray = [NSArray arrayWithObjects:..., nil];
theClassInstance.param = filledArray;
You will have retained a non-mutable array.
Edit: To debug the setting of param, you could do the following in your .m:
#dynamic param;
- (NSMutableArray*)param { return param; }
- (void)setParam:(NSMutableArray*)newArray {
NSLog(#"setting new param from class: %#",
NSStringFromClass([newArray class]));
[newArray retain];
[param release];
param = newArray;
}
What does your init method look like? It should look something like this...
- (id)init
{
self = [super init];
self.param = [NSMutableArray array];
return self;
}
After struggling a lot i found the solution for my problem. In my case the problem was,
I have a mutable dictionary and array
#property(strong,nonatomic)NSMutableDictionary *dictInfo;
#property(retain,nonatomic) NSMutableArray *userAccountsList;
And I am adding server array list to userAccountsList array like this
self.dictInfo = [jsonObject valueForKey:#"customerAccountList"];
I have taken another array and adding server array list to that array
array = [self.dictInfo valueForKey:#"banker"];
and finally adding array to userAccountsListArray like this
userAccountsList = [NSMutableArray arrayWithArray:array];
And here adding additional object to array
[userAccountsList addObject:#"Other Account"];//I was getting error here.
[tableViewObj reloadData];
Hope it helps someone. Please vote up if it helps.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:managedObjectContext];
That line doesn't seem to work anymore (I'm pretty sure its that line).
I can't seem to work out whats the problem. The application worked perfectly on Xcode with iOS 4.1 and now crashes with this error in the console:
2010-12-07 17:12:27.552 SMSApp[9222:207] +[ persistentStoreCoordinator]: unrecognized selector sent to class 0x5b14580
2010-12-07 17:12:27.553 SMSApp[9222:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[ persistentStoreCoordinator]: unrecognized selector sent to class 0x5b14580'
*** Call stack at first throw:
(
0 CoreFoundation 0x01547be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0169c5c2 objc_exception_throw + 47
2 CoreFoundation 0x015497bb +[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x014b9366 ___forwarding___ + 966
4 CoreFoundation 0x014b8f22 _CF_forwarding_prep_0 + 50
5 CoreData 0x00e6f3ca +[NSEntityDescription entityForName:inManagedObjectContext:] + 42
6 SMSApp 0x000046b9 -[MessagesRootViewController reloadMessages:] + 146
7 SMSApp 0x00004a09 -[MessagesRootViewController viewDidLoad] + 85
8 UIKit 0x0052265e -[UIViewController view] + 179
9 UIKit 0x00520a57 -[UIViewController contentScrollView] + 42
10 UIKit 0x00531201 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
11 UIKit 0x0052f831 -[UINavigationController _layoutViewController:] + 43
12 UIKit 0x00530b4c -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
13 UIKit 0x0052b606 -[UINavigationController _startDeferredTransitionIfNeeded] + 266
14 UIKit 0x00643e01 -[UILayoutContainerView layoutSubviews] + 226
15 QuartzCore 0x010b4451 -[CALayer layoutSublayers] + 181
16 QuartzCore 0x010b417c CALayerLayoutIfNeeded + 220
17 QuartzCore 0x010ad37c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
18 QuartzCore 0x010ad0d0 _ZN2CA11Transaction6commitEv + 292
19 UIKit 0x0047719f -[UIApplication _reportAppLaunchFinished] + 39
20 UIKit 0x00477659 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 690
21 UIKit 0x00481db2 -[UIApplication handleEvent:withNewEvent:] + 1533
22 UIKit 0x0047a202 -[UIApplication sendEvent:] + 71
23 UIKit 0x0047f732 _UIApplicationHandleEvent + 7576
24 GraphicsServices 0x01b2ca36 PurpleEventCallback + 1550
25 CoreFoundation 0x01529064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
26 CoreFoundation 0x014896f7 __CFRunLoopDoSource1 + 215
27 CoreFoundation 0x01486983 __CFRunLoopRun + 979
28 CoreFoundation 0x01486240 CFRunLoopRunSpecific + 208
29 CoreFoundation 0x01486161 CFRunLoopRunInMode + 97
30 UIKit 0x00476fa8 -[UIApplication _run] + 636
31 UIKit 0x0048342e UIApplicationMain + 1160
32 SMSApp 0x000025c4 main + 102
33 SMSApp 0x00002555 start + 53
)
terminate called after throwing an instance of 'NSException'
Any idea where this error is coming from or what is causing it?
Just to let you know as well, upgrading to XCode with iOS 4.2 caused some of the files to be deleted from my project. I don't know why this was, whether it was because they were linked files and not actually in the folder I dunno.
Any ideas?
Thanks
// EDIT
This method is in the AppDelegate:
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
// EDIT AGAIN
- (void)reloadMessages:(NSNotification *)notification {
NSLog(#"RECIEVED NEW MESSAGES TO MessagesRootViewController");
NSLog(#"%#",managedObjectContext);
// we need to get the threads from the database...
NSFetchRequest *theReq = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:self.managedObjectContext];
[theReq setEntity:entity];
threads = [NSArray arrayWithArray:[managedObjectContext executeFetchRequest:theReq error:nil]];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if(notification != nil){ // if its been caused by a notification
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"New Message" message:#"A new message has been received" delegate:nil cancelButtonTitle:#"Thanks" otherButtonTitles:nil];
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];
[alert release];
}
}
// EDIT 3
If I put this code in the applicationDidFinishLoading of my app delegate it works fine!
NSFetchRequest *theReq = [[NSFetchRequest alloc] init];
NSEntityDescription *theEntity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:self.managedObjectContext];
[theReq setEntity:theEntity];
NSArray *theThreads = [NSArray arrayWithArray:[self.managedObjectContext executeFetchRequest:theReq error:nil]];
After having a quick look at your code I think I found a couple of parts that needed attention. I'll try and break them down below:
SMSAppAppDelegate
1) Notice that in your interface file, you declare your CoreData variables with an underscore at the end of the variable name. Then you create properties for each of the ivar without the underscore. That is all fine as long as you #synthesize them making the correct assignment, which seems to be missing from your implementation:
#synthesize managedObjectContext=managedObjectContext_;
#synthesize managedObjectModel=managedObjectModel_;
#synthesize persistentStoreCoordinator=persistentStoreCoordinator_;
DownloadContacts
1) In this class you are calling the managedObjectContext directly through the variable. I wouldn't recommend that but this is not your actual problem. Notice that you release the managedObjectContext on dealloc even though you have no ownership of it!
2) What I would do in this case is declare a property for the context and always access it via the property. Also if you rename your instance variable to include an underscore at the end you are minimising your chances of accessing it directly (i.e. without using self.) and it will make it easier for you to find where in this class you are actually doing that (there are a couple of places from memory).
So in your interface file, rename managedObjectContext ivar and declare a property:
NSManagedObjectContext *managedObjectContext_;
...
#property (nonatomic, retain) NSManagedObjectContext managedObjectContext;
And don't forget to make the assignment on #sythesize and release on dealloc, since you are using a retain property:
#synthesize managedObjectContext=managedObjectContext_;
...
[managedObjectContext_ release];
Then if you try and compile you will get two or three errors of unrecognised instance variable which is where you have to go and change it to self.managedObjectContext
MessagesRootViewController
And finally I'd recommend you go through the same process in your MessagesRootViewController but this one should still work fine as is!
See how you go and let me know if any of the above is not clear!
Cheers,
Rog
I'm assuming you're doing something like:
[ClassName persistentStoreCoordinator]
Make sure ClassName is defined and has the persistentStoreCoordinator class method. Perhaps the file that did these things got deleted?
Matt
Your database might be corrupted, try resetting the iOS simulator
by clicking on iOS Simulator>Reset contents and settings.
Edit:
It looks like you're trying to call a selector that doesn't exist. Try figuring out which files were deleted, as it seems like you have a method that is called that can't be found at runtime. Did your core data classes get erased, maybe?
So, I'm debugging an app I'm building and using the description method to help me find the problem. But instead of giving me the app as a string it is printing out parentheses instead. Please help!
Here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
reminders = [[NSMutableArray alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[
NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
NSLog(#"IT'S HERE %#", [reminders description]);}
...
and the error:
[Session started at 2010-10-04 22:15:16 -0400.]
2010-10-04 22:15:17.434 Reminders[5824:207] ******* Accessibility Status Changed: On
2010-10-04 22:15:17.464 Reminders[5824:207] ********** Loading AX for: com.yourcompany.Reminders ************
2010-10-04 22:15:17.506 Reminders[5824:207] IT'S HERE (
)
2010-10-04 22:15:17.510 Reminders[5824:207] Hello
2010-10-04 22:15:17.512 Reminders[5824:207] (
)
2010-10-04 22:15:17.514 Reminders[5824:207] PVC: <UITableView: 0x602d600; frame = (0 20; 320 460); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x5f3f3b0>; contentOffset: {0, 0}>
2010-10-04 22:15:17.514 Reminders[5824:207] It's here
2010-10-04 22:15:17.515 Reminders[5824:207] Loaded
2010-10-04 22:15:17.520 Reminders[5824:207] -[__NSCFArray name]: unrecognized selector sent to instance 0x6a4b640
2010-10-04 22:15:17.523 Reminders[5824:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray name]: unrecognized selector sent to instance 0x6a4b640'
*** Call stack at first throw:
(
0 CoreFoundation 0x0248bb99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x025db40e objc_exception_throw + 47
2 CoreFoundation 0x0248d6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x023fd2b6 ___forwarding___ + 966
4 CoreFoundation 0x023fce72 _CF_forwarding_prep_0 + 50
5 Reminders 0x00003aa9 -[RootViewController tableView:cellForRowAtIndexPath:] + 300
6 UIKit 0x00090d6f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619
7 UIKit 0x00086e02 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
8 UIKit 0x0009b774 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
9 UIKit 0x000937ec -[UITableView layoutSubviews] + 242
10 QuartzCore 0x03f60481 -[CALayer layoutSublayers] + 177
11 QuartzCore 0x03f601b1 CALayerLayoutIfNeeded + 220
12 QuartzCore 0x03f592e0 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302
13 QuartzCore 0x03f59040 _ZN2CA11Transaction6commitEv + 292
14 UIKit 0x0002204e -[UIApplication _reportAppLaunchFinished] + 39
15 UIKit 0x00022477 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 545
16 UIKit 0x0002c3ec -[UIApplication handleEvent:withNewEvent:] + 1958
17 UIKit 0x00024b3c -[UIApplication sendEvent:] + 71
18 UIKit 0x000299bf _UIApplicationHandleEvent + 7672
19 GraphicsServices 0x026fa822 PurpleEventCallback + 1550
20 CoreFoundation 0x0246cff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
21 CoreFoundation 0x023cd807 __CFRunLoopDoSource1 + 215
22 CoreFoundation 0x023caa93 __CFRunLoopRun + 979
23 CoreFoundation 0x023ca350 CFRunLoopRunSpecific + 208
24 CoreFoundation 0x023ca271 CFRunLoopRunInMode + 97
25 UIKit 0x00021c6d -[UIApplication _run] + 625
26 UIKit 0x0002daf2 UIApplicationMain + 1160
27 Reminders 0x00002078 main + 102
28 Reminders 0x00002009 start + 53
)
terminate called after throwing an instance of 'NSException'
Here's the method that you asked for fluchtpunkt
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
Reminder *theReminder = [reminders objectAtIndex:indexPath.row];
cell.textLabel.text = theReminder.name;
return cell;
}
those parentheses are the output I would expect if I NSLog an empty array.
This is absolutely correct.
the exception is raised because you try to call a name method on an NS(Mutable)Array. And arrays don't respond to name.
To find the cause of this Exception post the code of this method in your RootViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath