I am a novice programmer. Because i'm a newby at Stackoverflow I cannot comment someones anwser yet. I got a question about this post : How to use NSUserDefaults to save data from ViewController and retrieve it to TableViewController when app reruns
I try to solve the problem and I read many topics on Stackoverflow, but I couldn't find the solution. I have the same code as Rhenzzz and I implemented the solution explained by Jay.
I have an error in cellForRowAtIndexPath method at the line NSString *itemWish = itemDictionary[#"itemWish"];.
Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[WishListItem objectForKeyedSubscript:]: unrecognized selector sent to instance 0x9dc4d80'
My full method is :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"wishlistCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *itemDictionary = self.wishlistItem[indexPath.row];
NSString *itemWish = itemDictionary[#"itemWish"];
cell.textLabel.text = itemWish;
return cell;
}
EDIT :
I forget to precise that my error occurs when I add a new item. The tableview displays datas when I launch the App. But when I add data on my ViewController and then save & go back to the Tableview by clicking on my Done button, I have the error describe above.
So I put some NSLog in cellForRowAtIndexPath : NSLog(#"Display the dictionary:%#",itemDictionary ); and NSLog(#"Display the item:%#",itemWish );. Everything is right.
So my problem comes certainly from the IBAction :
- (IBAction)unwindToList:(UIStoryboardSegue *)unwindSegue {
AddItemViewController *source = [unwindSegue sourceViewController];
WishlistItem *item = source.wishItem;
if (item != nil) {
[self.wishlistItem addObject:item];
[self.tableView reloadData];
}
}
If I delete the [self.tableView reloadData]; the error disappears but obviously my Tableview is not auto-updated.
Thanks for your help !
Given the error, it is clear that self.wishlistItem is an array of WishListItem objects and not an array of dictionaries. You should change these two lines:
NSDictionary *itemDictionary = self.wishlistItem[indexPath.row];
NSString *itemWish = itemDictionary[#"itemWish"];
to:
WishListItem *wishListItem = self.wishlistItem[indexPath.row];
NSString *itemWish = wishListItem.somePropertyGivingTheDesiredValue;
where obviously you need to use the appropriate property on wishListItem to get the value you want from it.
Related
I need to pass an array of CoreData entities from my main view to a TableViewController.
I used a lot of stackoverflow posts to help myself with that, and thought it worked.
But when I build my app, I have a thread problem, displaying:
[NSTaggedPointerString count]: unrecognized selector sent to instance".
I did some checks and the problem is, in my tableView, the number of Row is set to 0.
So here is my code :
My prepareForSegue function in my MainViewController.m:
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"sgPushDetail"])
{
checkDataSavedTableViewController *detail = segue.destinationViewController;
detail.datasToDisplay = _listOfDatas;
}
}
listOfDatas is an NSArray of NSManagedObject, declared in my
MainViewController.h
datasToDisplay is an NSArray declared in my TableViewController.
Here is my function to put my datas in the TableViewController:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"dataCells" forIndexPath:indexPath];
NSString *rowArray = self.datasToDisplay[indexPath.row];
cell.textLabel.text = rowArray;
return cell;
}
(But the error appears in the ViewDidLoad so meeeh)
How can I proceed further?
put break point in prepareforsegue. And check your array. I think your array is nil so that your table view is not getting data. Put neccessary breakpoints or you can prints array in prepareforsegue and in viewdidload of tableviewcontroller and check you are getting data in array!
Hope this will help :)
Your error is in NSString *rowArray = self.datasToDisplay[indexPath.row];
datasToDisplay is an Array of NsManagedObject not an array of Strings. So you need to get string value from your NsManagedObject :
NSString *rowArray = [self.datasToDisplay[indexPath.row] valueForKey: #"stringKey"]
OK I AM STUPID.
Since I use CoreData, I already have a list of my entities. I don't need my NSArray of randomMeh, I just need that:
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Contact" inManagedObjectContext:context];
I am have an NSDictionary which multiple dictionaries like this:
{
complete = 0;
description = Description;
"due_date" = "2014-02-28 16:30:03";
name = Task;
priority = 2;
"task_id" = 1;
"user_id" = 1;
},
{
complete = 0;
description = "";
"due_date" = "0000-00-00 00:00:00";
name = "";
priority = 0;
"task_id" = 2;
"user_id" = 1;
}
I would like to display each instance of "name" in my UITableView
I have tried this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
for (task in tasks) {
cell.textLabel.text = [[task objectAtIndex:indexPath.row] valueForKey:#"name"];
}
return cell;
}
But the app crashes each time I attempt to do run it.
What am I doing wrong?
Here is the error I get:
Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:]
Change your code to look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
cell.textLabel.text = [[tasks objectAtIndex:indexPath.row] valueForKey:#"name"];
return cell;
}
The problem was that task was a dictionary, so it didn't respond to objectAtIndex:.
BTW, you need to create or dequeue a UITableViewCell instance as well, but I simply corrected your crashing issue for you.
The reason you are getting a crash is because you are returning nil from tableView:cellForRowAtIndexPath:.
I think you are also misunderstanding how this table view data source method works. It gets called once per table cell in your table (hence why you return a UITableViewCell from it...). You don't need to be looping over your data collection inside it - you should be getting the correct data object from your collection based on the indexPath.
On top of that, as others have said, if tasks is in fact an NSDictionary, then it won't respond to objectAtIndex. In all likelihood, you probably want your data collection to be an NSArray, if it isn't already.
Edit:
Judging by the error you are getting, tasks is in fact an NSArray (as the error is caused by returning nil from tableView:cellForRowAtIndexPath:). Try the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCellIdentifier" forIndexPath:indexPath];
NSDictionary *task = [tasks objectAtIndex:indexPath.row];
cell.textLabel.text = [task objectForKey:#"name"];
return cell;
}
Edit 2:
Also, you should be using objectForKey: instead of valueForKey:.
Dictionaries don't have indices.
You can't call a objectAtIndex: method on a dictionary, that's why your app is crashing. Instead, you need to use objectForKey: with the appropriate key to get the value you want.
Try storing those NSDictionary's in an NSArray. An NSArray will allow you to hold them, along with accessing objects with "objectAtIndex".
If you need to add NSDictionary's at run-time, try using an NSMutableArray, which allows you to add and remove array objects when needed.
Hi I'm studying a 9TH lesson of iTunesU CS193P about table view and compiler report me this error
NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
my simulator is iPad 6.1
so I have
a class called GraphViewController.m
#define FAVORITE_KEY #"GraphViewController.Favorite"
- (IBAction)addFavorite:(id)sender
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *favorites = [[defaults objectForKey:FAVORITE_KEY] mutableCopy];
if (!favorites) favorites = [NSMutableArray array];
[favorites addObject:self.program];
// NSLog(#"contenuto favorites %#",favorites);
[defaults setObject:favorites forKey:FAVORITE_KEY];
[defaults synchronize];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"GraphTableView"]) {
NSArray *program = [[NSUserDefaults standardUserDefaults]objectForKey:FAVORITE_KEY];
[segue.destinationViewController setPrograms:program];
}
}
(setPrograms is the setter where i have the data to send at my tableviewcontroller called CalculatorTVC.m)
a class called CalculatorTVC.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.programs count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellTable";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
id program = [self.programs objectAtIndex:indexPath.row];
cell.textLabel.text = [#"y = " stringByAppendingString:[CalculatorBrain descriptionProgram:program]];
NSLog(#"contenuto di program %#",program);
return cell;
}
(programs is a public property where I put the data from GraphViewController.m)
In my storyboard I have a split view ...in MasterViewController i have toolbar with bar button item wired with table view controller (CalculatorTVC.m) in popover style identifier is GraphTableView and i have a round rect button that is addFavorite describe here up
the error is
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
* First throw call stack:
(0x1ca1012 0x10dee7e 0x1ca0deb 0x1d21c4f 0x1d21911 0x4a5b 0x8f65 0xdd8fb 0xdd9cf 0xc61bb 0xd6b4b 0x732dd 0x10f26b0 0x229dfc0 0x229233c 0x22a0238 0x6b6e3 0x4f1476 0x870989a 0x4f2555 0x489ef9 0x46ab99 0x46ac14 0x10f2705 0x262c0 0x262a64 0x10f2705 0x262c0 0x26258 0xe7021 0xe757f 0xe66e8 0x55cef 0x55f02 0x33d4a 0x25698 0x1bfcdf9 0x1bfcad0 0x1c16bf5 0x1c16962 0x1c47bb6 0x1c46f44 0x1c46e1b 0x1bfb7e3 0x1bfb668 0x22ffc 0x24bd 0x23e5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
please help me
thanks for your patience
regards
ok I find where it crashes....
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellTable";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
id program = [self.programs objectAtIndex:indexPath.row];
cell.textLabel.text = [#"y = " stringByAppendingString:[CalculatorBrain descriptionProgram:program]];
NSLog(#"contenuto di program %#",program);
return cell;
}
the crash in the line
cell.textLabel.text = [#"y = " stringByAppendingString:[CalculatorBrain descriptionProgram:program]];
if I put NSLOG before this line i see in the output NSLOG result...but if I put NSLOG after this I don't see anything in the output
NSArray *program = [[NSUserDefaults standardUserDefaults]objectForKey:FAVORITE_KEY];
[segue.destinationViewController setPrograms:program];
Here you're passing an immutable array to the destination view controller. If it is expecting a mutable array and tries to modify it, you'll get that crash. You need mutableCopy here as well.
If the property should be a mutable array, you should get compiler warnings. Don't ignore these!
You're crashing on remove, not add, by the way, so you haven't included the right code in your question. Enable exception breakpoints to find the line you're crashing on.
In a tabbed application developed in Xcode 4.2, I found a confusing problem: In one of tabs, there is a tableview to show something like index. So I initialized an array in viewDidLoad() method. for example:
- (void)viewDidLoad
{
NSArray *array = [NSArray arrayWithObjects:#"abc", #"def", #"ghi", #"jkl", #"mno", nil];
self.arrayList = array;
[array release];
[super viewDidLoad];
}
Then I use this arrayList in other methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayList count];
}
- (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];
}
cell.textLabel.text = [arrayList objectAtIndex:indexPath.row];
return cell;
}
But Xcode gives me the "EXC_BAD_ACCESS" signal every time I run it. I put some breakpoints, and found that the array was created successfully in viewDidLoad(), but before running the method cellForRowAtIndexPath:(NSIndexPath *)indexPath, it became a freed object. That's the reason why I got that signal and the application crashed. So, how to solve this problem?
Btw, the view controller where the problem occurs is created from UIViewController, not UITableViewController. But I put a table view and linked its datasource and delegate to File's Owner. Does that matter?
You must not release the array. The +arrayWithObjects: convenience method returns an unowned array. You never took ownership of the array, therefore you must not relinquish ownership. Remove the the line [array release] and you will not see this error anymore (at least not for that reason).
I am creating a simple app to select video urls out of a UITable. I have hooked my data source and delegate to a UIViewController subclass and the table is filled correctly. Also, it recognizes selections and prints to the log.
My issue is that it gets a "EXC_BAD_ACCESS" and crashes when I select a cell. I am looking through the code and the error propagates to this method:
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* cellIdentifier = #"SelectionIdentifier";
//Errors start happening this next line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
//NSString* str = [[videos objectAtIndex:[indexPath row]] lastPathComponent];
NSString* test = #"test";
[[cell textLabel] setText:test];
return cell;
}
-(void) tableView:(UITableView*)myTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// NSLog(#"Selected!");
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
return [videos count];
}
I'm not sure why this error is getting thrown in this method. Any fixes? I double checked to make sure the videos array wasn't nill.
I did another app that used this same method and it doesn't cause these errors.
Any help or suggestions would be greatly appreciated!
Instead of testing if(cell == nil) try using if(!cell). Honestly I'm not sure this is the issue, but after reviewing this I do not think that the error is not actually inside this method (it may somehow be related which is why it brings you here).
If this is only after you select a cell though, why is this method being called?
I think you should also call this method.Because this is preliminary delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
After seeing your tableView i am not finding any problem at all.Try that may be it will be solve.