UITableView not reloading section and contents - iphone

I have a refresh button in the toolbar that regenerates an NSArray and attempts to reload the contents of the table.
However, whether I have:
if (boolCondition) {
[self refreshTableDataSet];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kTableSectionOfInterest] withRowAnimation:UITableViewRowAnimationFade];
}
or:
if (boolCondition) {
[self refreshTableDataSet];
[self.tableView reloadData];
}
About every other attempt to refresh the table fails. Sometimes it works, sometimes not.
I have some NSLog statements in -tableView:cellForRowAtIndexPath: to let me know when this method is being fired. When the refresh fails, I do not see the output of these NSLog statements.
Is there something I'm missing about reloading a table view, when I have new data?
EDIT
In my -refreshTableDataSet method:
- (void) refreshTableDataSet {
NSSortDescriptor *_objectTypeSorter = [[[NSSortDescriptor alloc] initWithKey:#"object.type" ascending:YES] autorelease];
NSSet *_objectSet = [managedObjectContext fetchObjectsForEntityName:#"Object" withPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:#"group.name like '%#'", [group name]]]];
self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];
}
In my table view -tableView:cellForRowAtIndexPath: method:
...
Object *_object = [self.objects objectAtIndex:indexPath.row];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = _object.name;
cell.detailTextLabel.text = _object.type;
cell.imageView.image = [UIImage imageNamed:#"GroupType.png"];
cell.accessoryView = [self imageViewForObjectDetailType:_object.type];
...
I have a method for the accessoryView called -imageViewForObjectDetailType, which just returns a UIImageView:
return [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"GenericObjectDetailType.png"]] autorelease];
Are there retain and/or release messages that I am missing?

I'm sure you've checked this, but I see random behavior like this if I have an NSArray that wasn't retained and passed on to a tableview.
Looking at your added code, I don't see anything wrong at first glance - here are some tips:
1.In:
self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];
If objects is a #property with retain attribute, then you don't need to retain it here again. Not why it would fail though.
2.In your cellForRowAtIndexPath:, you do have something like:
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
just before the if (cell == nil), right?
3.You might want to NSLog the value of object when you get it from the array in
Object *_object = [self.objects objectAtIndex:indexPath.row];
4.Break this up onto multiple lines and look at all the return values with NSLog to make sure they all succeed every time you refresh.
self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];
5.Double check this to make sure your fetch is getting you what you expect:
NSSet *_objectSet = [managedObjectContext fetchObjectsForEntityName:#"Object" withPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:#"group.name like '%#'", [group name]]]];
You can NSLog the [_objectSet count] to watch to see whether an unsuccessful refresh gives you a bad count.
Hope this helps.

Related

NSMutableArray, pList, Tableview muddle and meltdown

I have a preferences view which shows a different table view depending on which Segmented Control is clicked.
I hard coded some NSMutableArrays to test basic principles:
prefsIssuesList = [[NSMutableArray alloc] init];
[prefsIssuesList addObject:#"Governance"];
[prefsIssuesList addObject:#"Innovation and technology"];
...etc
prefsIndustriesList = [[NSMutableArray alloc] init];
[prefsIndustriesList addObject:#"Aerospace and defence"];
... etc
prefsServicesList = [[NSMutableArray alloc] init];
[prefsServicesList addObject:#"Audit and assurance"];
...etc
currentArray = [[NSMutableArray alloc] init];
currentArray = self.prefsIssuesList;
Then reload the tableview with currentArray, adding a UITableViewCellAccessoryCheckmark.
Everything works fine.
But now I want to store wether the checkmark is on or off in a pList file, and read this back in.
Ideally want to a plist like this
Root Dictionary
Issues Dictionary
Governance Number 1
Innovation and technology Number 0
etc
I've got as far as working this out
// Designate plist file
NSString *path = [[NSBundle mainBundle] pathForResource: #"issues" ofType:#"plist"];
// Load the file into a Dictionary
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.allNames= dict;
[dict release];
NSLog(#"Dict is %#", allNames); // All the data in the pList file
NSMutableArray *issueSection = [allNames objectForKey:#"Issues"];
NSLog(#"Issues is %#", issueSection); // The data is the Issues Section
NSString *issueVal = [issueSection objectForKey:#"Governance"];
NSLog(#"Governance is %#", issueVal); //The value of the Governance key
But what I really want to do is loop through the Issues Dictionary and get the key/value pairs so
key = cell.textLabel.text
value = UITableViewCellAccessoryCheckmark / UITableViewCellAccessoryNone
depending wether it's 1 or 0
I'm assuming that I can still assign one of the three NSMutableArrays to currentArray as I did in the hardcoded version, and use currentArray to reload the tableview.
Then amend this code to build the tableview
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
static NSString *CellIdentifier = #"Cell";
//UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell=[[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier: CellIdentifier] autorelease];
}
cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
But my brain has melted, I've spent about six hours today reading up on pLists, NSArrays, NSMutableDisctionaries, standardUserDefaults to little avail.
I've managed to UITableViews inside UINavigationViews, use SegmentedControls, download asynchronous XML, but now I'm finally stuck, or fried, or both. Over what should be fairly simple key/value pairs.
Anyone care to give me some idiot pointers?
Typing it out led to another post with that one little word I needed to get me back on track :)
Use key/value pairs in a pList to stipulate the name of the cell and wether it was selected or not by the user.
plist is based on a structure like this
Root Dictionary
Services Dictionary
Peaches String 1
Pumpkin String 0
Here's how I grabbed three Dictionary arrays from a pList and used the key/value pairs to reload a tableview depending on which segmentControl was touched:
- (void)viewDidLoad {
[super viewDidLoad];
// Designate plist file
NSString *path = [[NSBundle mainBundle] pathForResource: #"issues" ofType:#"plist"];
// Load the file into a Dictionary
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.allNames= dict;
[dict release];
// Create the Named Dictionaries from Dictionary in pLIst
NSMutableDictionary *allIssues = [self.allNames objectForKey:#"Issues"];
self.prefsIssuesList = allIssues;
[allIssues release];
NSMutableDictionary *allIndustries = [self.allNames objectForKey:#"Industries"];
self.prefsIndustriesList = allIndustries;
[allIndustries release];
NSMutableDictionary *allServices = [self.allNames objectForKey:#"Services"];
self.prefsServicesList = allServices;
[allServices release];
// Assign the current Dictionary to out placeholder Dictionary
currentDict = [[NSMutableDictionary alloc] init];
currentDict = self.prefsIssuesList;
}
Then styling the table cells
- (UITableViewCell *)tableView:(UITableView *)prefsTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
NSArray *keysArray = [self.currentDict allKeys];
NSString *theKey = [keysArray objectAtIndex:row];
NSString *theValue = [self.currentDict objectForKey: [keysArray objectAtIndex:row]];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell=[[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier: CellIdentifier] autorelease];
}
cell.textLabel.text = theKey;
if (theValue == #"0") {
cell.accessoryType = UITableViewCellAccessoryNone;
}else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
return cell;
}
The if clause at the end doesn't seem to be working, I'll post that as a new question (unless anyone comments quickly!)
Finally the segmentControls assign the different dictionaries to the placeholder array and reload the tableview
This took me a very long day to figure out (as a noobie) so I hope it helps someone
-(IBAction) segmentedControlIndexChanged{
switch (self.segmentedControl.selectedSegmentIndex) {
case 0:
//currentArray = self.prefsIssuesList;
currentDict = self.prefsIssuesList;
break;
case 1:
//currentArray = self.prefsIndustriesList;
currentDict = self.prefsIndustriesList;
break;
case 2:
//currentArray = self.prefsServicesList;
currentDict = self.prefsServicesList;
break;
default:
//currentArray = self.prefsIssuesList;
currentDict = self.prefsIssuesList;
break;
}
[prefsTableView reloadData];
}
Shout if there's a neater or better way of d

Dealing with editable items in a filtered UITable with an NSMutableArray copy

I have a UITable with a datasource that is set to a 'copy' of the original data. I use this copy to displayed filtered results (either 'All' or only those that are 'checked' with a UISwitch in each row). My logic for doing the filtering is here:
-(void)filterItems {
[tableData removeAllObjects];
if (checkedOrNotSwitch.selectedSegmentIndex == 0) {
[tableData addObjectsFromArray:self.defaultChecklistItemsArray];
} else {
for (NSMutableDictionary *sectionDict in self.defaultChecklistItemsArray) {
NSMutableArray *newItemsArray = [[NSMutableArray alloc] init];
[newItemsArray removeAllObjects];
for (NSMutableDictionary *itemDict in [sectionDict objectForKey:#"categoryItems"]) {
if ([[itemDict objectForKey:#"isComplete"] boolValue]) {
[newItemsArray addObject:itemDict];
}
}
if ([newItemsArray count] > 0) {
NSMutableDictionary *newSectionDict = [[NSMutableDictionary alloc] initWithDictionary:sectionDict];
[newSectionDict setObject:newItemsArray forKey:#"categoryItems"];
[tableData addObject:newSectionDict];
[newSectionDict release];
}
}
}
[checklistTable reloadData];
}
The filtering itself now works correctly. In my custom cell, each row has a UISwitch. The switch runs this function when its changed:
-(IBAction) switchValueChanged{
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
[self.parentController updateCompletedStatusAtIndexPath:indexPath toStatus:isCompleted.on];
}
The function above is in the class for the tableviewcell itself. The function I call in the superview is this:
-(void)updateCompletedStatusAtIndexPath:(NSIndexPath *)indexPath toStatus:(BOOL)status{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSMutableDictionary *currentsection = [[NSMutableDictionary alloc] initWithDictionary:[tableData objectAtIndex:section]];
NSMutableArray *itemsArray = [[NSMutableArray alloc] initWithArray:[currentsection objectForKey:#"categoryItems"] copyItems:YES];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithDictionary:[itemsArray objectAtIndex:row]];
NSLog(#"BOOL = %#\n", (status ? #"YES" : #"NO"));
[tempDict setValue:[NSNumber numberWithBool:status] forKey:#"isComplete"];
[itemsArray replaceObjectAtIndex:row withObject:tempDict];
[currentsection setValue:itemsArray forKey:#"categoryItems"];
[tableData replaceObjectAtIndex:section withObject:currentsection];
[tempDict release];
[itemsArray release];
[currentsection release];
[checklistTable reloadData];
}
Before I implemented the filtering and used the logic above on self.defaultChecklistItemsArray directly, it worked and saved the data when the switch was flipped.
Now when I first enter the app, it loads the array of data from nsuserdefaults. I navigate to the view with the table and it displays the data correctly there with the UISwitches all in the correct position given the data (some on, some off). When I tap one of the switches, then click the segmentedcontrol that does the filtering, the data reverts back to the state it was loaded in, implying that the flipping of the switch did not actually effect the data at all (even though I don't think I did a deep copy anywhere here so I figured it should be doing the right thing). Any suggestions?

-[NSCFString objectAtIndex:]: unrecognized selector

I have this little problem I couldn't find in Google:
UITableView works fine until I start scrolling.
Error Message: `-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5f24870 `
Method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length]-1];
//populate cell
cell.textLabel.text = [[myArray objectAtIndex: storyIndex] objectForKey: #"subject"];
return cell;
}
Just guessed that was the "problem"-method... if you need more infos: please tell me :)
thanks for all your help!
EDIT:
myArray is just the normal NSArray *myArray
It's a sorted Array ->
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"lesson" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
resultArray (NSMutableArray) is the Result of an XML-Parser.. hope you can see my problem..
It means that you're sending an objectAtIndex: messages to an object of type NSString (or possibly CFString). Of course you're expecting myArray to be an array and not a string.
What probably happened is that your array is being released (almost certainly autoreleased) too early and that by the time the method above is called the memory that was being pointed at by myArray now holds a string.
In response to your edit...
This line:
myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
...is incorrect. The value is autoreleased. You need to retain it:
myArray = [[resultArray sortedArrayUsingDescriptors:sortDescriptors] retain];
Remember to release it before you close the view!
myArray is proberbly autoreleased. Use self.myArray to set the sorted array. (with the correct #property (retain) )
If you have correctly identified this method as the culprit I'm guessing this line is the problem:
cell.textLabel.text = [[myArray objectAtIndex: storyIndex] objectForKey: #"subject"];
To me it looks lime myArray is an instance of NSCFString and not a NSArray. You should start by double checking that and that you never assign anything but NSArray instances to myArray.
--edit--
Try
self.myArray = [resultArray sortedArrayUsingDescriptors:sortDescriptors];
That should correctly retain the array for yoy to make sure it is not garbage collected and replaced with a rouge string :)
If myArray is an instance variable instead of a property, try:
myArray = [[resultArray sortedArrayUsingDescriptors:sortDescriptors] retain];

Core Data Error "Fetch Request must have an entity"

I've attempted to add the TopSongs parser and Core Data files into my application, and it now builds succesfully, with no errors or warning messages. However, as soon as the app loads, it crashes, giving the following reason:
UPDATE: I've got it all working, but my TableView doesn't show any data, and the app doesn't respond to the following breakpoints.
Thanks.
UPDATE: Here's the new code that doesn't respond to the breakpoints.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)table {
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.tableView = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellIdentifier = #"SongCell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
}
Incident *incident = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(#"#%d %#", #"#%d %#"), incident.title];
return cell;
}
- (void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[table deselectRowAtIndexPath:indexPath animated:YES];
self.detailController.incident = [fetchedResultsController objectAtIndexPath:indexPath];
[self.navigationController pushViewController:self.detailController animated:YES];
}
UPDATE: Here's the code where all instances of fetch are found.
- (Category *)categoryWithName:(NSString *)name {
NSTimeInterval before = [NSDate timeIntervalSinceReferenceDate];
#ifdef USE_CACHING
// check cache
CacheNode *cacheNode = [cache objectForKey:name];
if (cacheNode != nil) {
// cache hit, update access counter
cacheNode.accessCounter = accessCounter++;
Category *category = (Category *)[managedObjectContext objectWithID:cacheNode.objectID];
totalCacheHitCost += ([NSDate timeIntervalSinceReferenceDate] - before);
cacheHitCount++;
return category;
}
#endif
// cache missed, fetch from store - if not found in store there is no category object for the name and we must create one
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:self.categoryEntityDescription];
NSPredicate *predicate = [self.categoryNamePredicateTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:name forKey:kCategoryNameSubstitutionVariable]];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchResults = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
NSAssert1(fetchResults != nil, #"Unhandled error executing fetch request in import thread: %#", [error localizedDescription]);
Category *category = nil;
if ([fetchResults count] > 0) {
// get category from fetch
category = [fetchResults objectAtIndex:0];
} else if ([fetchResults count] == 0) {
// category not in store, must create a new category object
category = [[Category alloc] initWithEntity:self.categoryEntityDescription insertIntoManagedObjectContext:managedObjectContext];
category.name = name;
[category autorelease];
}
#ifdef USE_CACHING
// add to cache
// first check to see if cache is full
if ([cache count] >= cacheSize) {
// evict least recently used (LRU) item from cache
NSUInteger oldestAccessCount = UINT_MAX;
NSString *key = nil, *keyOfOldestCacheNode = nil;
for (key in cache) {
CacheNode *tmpNode = [cache objectForKey:key];
if (tmpNode.accessCounter < oldestAccessCount) {
oldestAccessCount = tmpNode.accessCounter;
[keyOfOldestCacheNode release];
keyOfOldestCacheNode = [key retain];
}
}
// retain the cache node for reuse
cacheNode = [[cache objectForKey:keyOfOldestCacheNode] retain];
// remove from the cache
[cache removeObjectForKey:keyOfOldestCacheNode];
} else {
// create a new cache node
cacheNode = [[CacheNode alloc] init];
}
cacheNode.objectID = [category objectID];
cacheNode.accessCounter = accessCounter++;
[cache setObject:cacheNode forKey:name];
[cacheNode release];
#endif
totalCacheMissCost += ([NSDate timeIntervalSinceReferenceDate] - before);
cacheMissCount++;
return category;
}
And this one...
- (void)fetch {
NSError *error = nil;
BOOL success = [self.fetchedResultsController performFetch:&error];
NSAssert2(success, #"Unhandled error performing fetch at SongsViewController.m, line %d: %#", __LINE__, [error localizedDescription]);
[self.tableView reloadData];
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Song" inManagedObjectContext:managedObjectContext]];
NSArray *sortDescriptors = nil;
NSString *sectionNameKeyPath = nil;
if ([fetchSectioningControl selectedSegmentIndex] == 1) {
sortDescriptors = [NSArray arrayWithObjects:[[[NSSortDescriptor alloc] initWithKey:#"category.name" ascending:YES] autorelease], [[[NSSortDescriptor alloc] initWithKey:#"rank" ascending:YES] autorelease], nil];
sectionNameKeyPath = #"category.name";
} else {
sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:#"rank" ascending:YES] autorelease]];
}
[fetchRequest setSortDescriptors:sortDescriptors];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:sectionNameKeyPath cacheName:#"SongsCache"];
}
return fetchedResultsController;
}
your extra caching is probably a waste of cycles as Core Data performs its own caching internally. I am willing to bet you are slowing things down rather than speeding them up, not to mention the additional memory you are consuming.
Where are you setting categoryEntityDescription? That is now shown in the code you posted. It is probably nil.
Why are you retaining an NSEntityDescription?!? They are already in memory because of Core Data and retaining them is a waste which could lead to issues if Core Data wants to release it at some point.
update
Your caching is definitely not coming from Apple's code because they know that the cache is in Core Data.
As for the NSEntityDescription, again, do not retain the NSEntityDescription.
Are you 100% positive that the NSEntityDescription is not nil? Have you confirmed it in the debugger? Have you tested it with a freshly retrieved NSEntityDescription?
update
You need to learn to use the debugger as that will solve most of your coding issues. Put a breakpoint in this method and run your code in the debugger. Then when the execution stops on that break point you can inspect the values of the variables and learn what they are currently set to. That will confirm or deny your suspicions about what is and is not nil.
This error you are seeing happens when you fail to set the Entity in the NSFetchRequest which, based on your code, means that retained property is not being set before the code you have shown is being called.
Based on the code posted and the problem description, I suspect that the categoryEntityDescription property is returning nil.
I've seen this happen when the NSEntityDescription given to a fetch request is nil. The most likely cause of that is that you have a model entity that is named differently from the name you provided to entityForName. Barring that, it could be an error in configuration of your Core Data stack or a missing data model, but as a first step, I would recommend storing the result of entityForName in a local variable and breaking there to make sure it isn't nil.
Since you added the model file manually, is the .xcdatamodel file inside the Compile Sources step in your Target?
Go to the Targets entry in the Groups & Files pane in Xcode and click the disclosure triangle. Then click on the disclosure triangle for your app. Then check to see if it's in Compile Sources. If not, right click on Compile Sources and choose "Add -> Existing File..." and add it.
Edit based on update:
UPDATE: Here's the new code that
doesn't respond to the breakpoints.
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Is your view controller set as the UITableViewDataSource/UITableViewDelegate for your UITableView? If not, these methods will not get called.

Filter NSArray iphone

I use coredata to fill an array with data that is displayed in a tableview.
In the tableview, I have two section.
When a cell is pushed in section1, I want that cell to be moved to section2, and the other way around.
Im not quite sure how to accomplish this, and I been sitting trying to figure it out for about 8 hours now.
This is what I got so far:
I use this code to get the data:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"creationDate" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1];
NSMutableArray *sortedIngredients = [[NSMutableArray alloc] initWithArray:[event.tags allObjects]];
[sortedIngredients sortUsingDescriptors:sortDescriptors];
self.tagsArray = sortedIngredients;
[sortDescriptor release];
[sortDescriptors release];
[sortedIngredients release];
In didSelectRowForIndexPath, I figure out how to remove the cell:
Tag *tag = [tagsArray objectAtIndex:indexPath.row];
NSManagedObjectContext *context = event.managedObjectContext;
[context deleteObject:tag];
[tagsArray removeObject:tag];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
How do I insert this cell in section 2 in the tableView?
Should I create 2 arrays?
I tried some code that used NSDictiorary, like this:
[tableView addObject: sectionOneObject forKey:#"Section1"];
[tableView addObject: sectionTwoObjects forKey: #"Section2"];
But I never manage to get it to work.
Any help would be highly appreciated!
Thanks in advance
Check out -insertRowsAtIndexPaths:withRowAnimation, e.g.:
unsigned _insertionIndices[2] = {1,0}; // second section, first row
NSIndexPath *_insertionIndexPath = [[NSIndexPath alloc] initWithIndexes: _insertionIndices length:2];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:_insertionIndexPath] withRowAnimation: UITableViewRowAnimationRight];
[_insertionIndexPath release];