UITableView not updated

I am using the Core Data model and the table view of the UITableViewController. My model works well, but my tabular view does not update when I add an object to my model. The reason I believe that my model works is that when I add an entity, nothing is displayed in the view at runtime, however, if I cut out a task, run a new one, the entity that I suddenly created will appear in the table view .

Here is my table view controller - AudioTableViewController.h

#import <UIKit/UIKit.h> #import "Bank.h" #import "Player.h" @class Player; @interface AudioTableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> { Player *myMainMan; } -(void)addAudioEntityToArray:(AudioFile *)event; -(NSMutableArray *)recordingsArray; @end 

AudioTableViewController.m (implementation file)

 #import "AudioTableViewController.h" @implementation AudioTableViewController -(void)addAudioEntityToArray:(AudioFile *)event { NSIndexPath *indexPath; if(event.type) { [[MusikerViewController recordingsArray] addObject:event];//self? indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; }else { [[MusikerViewController downloadsArray] addObject:event]; indexPath = [NSIndexPath indexPathForRow:0 inSection:1]; } [[self tableView] setEditing:YES animated:NO]; [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; } - (void)viewDidLoad { [[self tableView] reloadData]; [super viewDidLoad]; self.title = @"Audio Files";//put this in application delegate self.navigationItem.leftBarButtonItem = self.editButtonItem; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. NSLog(@"Place I"); if(section == 0) { return [[MusikerViewController recordingsArray] count]; } else if (section == 1) { return [[MusikerViewController downloadsArray] count]; } } 

... more methods

Here is the part of my Bank class that may be relevant to Bank.h

 #import <Foundation/Foundation.h> #import <AudioToolbox/AudioToolbox.h> #import "AudioFile.h" #import "AudioTableViewController.h" #import "MusikerAppDelegate.h" @interface Bank : NSObject <UIAlertViewDelegate> { NSManagedObjectContext *managedObjectContext; AudioFile *sound; } @property (retain, nonatomic) NSManagedObjectContext *managedObjectContext; +(NSString *)getDataPath:(NSString *)fileExtDate; -(AudioFile *)addAudioFileEntityToModelWithDate:(NSDate *)theD andURLString:(NSString *)str; -(BOOL)removeAudioFromModel:(id)audio; -(NSMutableArray *)getFetchArray; @end 

Bank.m

 #import "Bank.h" @implementation Bank @synthesize managedObjectContext; - (AudioFile *)addAudioFileEntityToModelWithDate:(NSDate *)theD andURLString:(NSString *)str { sound = (AudioFile *)[NSEntityDescription insertNewObjectForEntityForName:@"AudioFile" inManagedObjectContext:managedObjectContext]; sound.creationDate = theD; sound.soundPath = str; //set the sound path to the sound file url [self alertForTitle]; return sound; } - (BOOL)saveContext { NSError *error = nil; if(!managedObjectContext) { NSLog(@"managedObejctContext problem at saveContext Bank"); } if (![managedObjectContext save:&error]) { return NO; } else { return YES; } } - (NSMutableArray *)getFetchArray { NSLog(@"ManagedObjectContext at getFetchArray"); NSLog(@"Context: %@",managedObjectContext); NSFetchRequest *request = [[NSFetchRequest alloc] init]; if(!managedObjectContext) { NSLog(@"There is no managedObjectContext in getFetchArray Bank"); } NSEntityDescription *entity = [NSEntityDescription entityForName:@"AudioFile" inManagedObjectContext:managedObjectContext]; [request setEntity:entity]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [request setSortDescriptors:sortDescriptors]; [sortDescriptors release]; [sortDescriptor release]; NSError *error = nil; NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; if (mutableFetchResults == nil) { NSLog(@"mutableFetchResults array is nil"); } [request release]; return mutableFetchResults; } + (NSString *)getDataPath:(NSString *)fileExtDate { NSLog(@"getDataPath called"); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; documentsDirectory = [documentsDirectory stringByAppendingPathComponent:@"Musik Directory"]; //changing the recording directory to Musik Directory NSError *error; if (![[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory]) { [[NSFileManager defaultManager] createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&error]; NSLog(@"In the if statement"); } NSString *docPath = [documentsDirectory stringByAppendingPathComponent:fileExtDate]; return docPath; } 

Player.h

 #import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> #import "Bank.h" @class Bank; @interface Player : NSObject <AVAudioPlayerDelegate, AVAudioRecorderDelegate> { Bank *daBank; AVAudioPlayer *musicPlayer; AVAudioRecorder *musicRecorder; NSDate *myDate; NSString *strPath; NSString *documentPath_; NSMutableArray *arrayListOfRecordSound; } -(void)playSoundFile:(NSString *)soundFilePath; -(BOOL)saveRecordingWithDate:(NSDate *)theD andURLString:(NSString *)str; -(void)recordSomething; -(void)playRecording; -(void)play; + (NSString *)dateString:(NSDate *)date; + (NSString *)dateString; @end 

Player.m

 - (Bank *)daBank { if(!daBank) { daBank = [[Bank alloc] init]; } return daBank; } -(BOOL)saveRecording { //this is the method that adds the new object to both the //model and view, the method that calls this method is not shown Bank *B = [MusikerViewController daBank]; AudioTableViewController *ATVC2 = [MusikerViewController ATVControl]; AudioFile *myAudioFileMusicX314 = [[B addAudioFileEntityToModelWithDate:myDate andURLString:strPath] retain]; myAudioFileMusicX314.type = true; [ATVC2 addAudioEntityToArray:myAudioFileMusicX314]; if(![B saveContext]) { NSLog(@"addAudioFileEntityToModel is returning a nil managedObjectContext"); return NO; } [myDate release]; [strPath release]; [myAudioFileMusicX314 release]; [ATVC2 release]; return YES; } 

Last but not least: MusikViewController.h

 #import <UIKit/UIKit.h> #import "Player.h" #import "Bank.h" #import <QuartzCore/QuartzCore.h> #import "MyButtonView.h" #import "AudioTableViewController.h" @class AudioTableViewController; @class Bank; @class Player; @interface MusikerViewController : UIViewController { ] BOOL *pressed; } Player *myMainMan; Bank *daBank; AudioTableViewController *ATVControl; NSMutableArray *recordingsArray; NSMutableArray *downloadsArray; + (Bank *)daBank; + (Player *)myMainMan; + (AudioTableViewController *)ATVControl; + (NSMutableArray *)recordingsArray; + (NSMutableArray *)downloadsArray; @end 

MusikViewController.m

 + (NSMutableArray *)recordingsArray { NSLog(@"recordingsArray called"); if(!recordingsArray) { recordingsArray = [[NSMutableArray alloc] init]; NSMutableArray *bigTempArray = [[[[Bank alloc] init] autorelease] getFetchArray]; //change this for(AudioFile *af in bigTempArray) if(af.type) { [recordingsArray addObject:af]; } NSLog(@"recordingsArray exists"); } return recordingsArray; } + (NSMutableArray *)downloadsArray { NSLog(@"recordingsArray called"); if(!downloadsArray) { downloadsArray = [[NSMutableArray alloc] init]; // if(!bigTempArray) NSMutableArray *bigTempArray = [[[[Bank alloc] init] autorelease] getFetchArray]; for(AudioFile *af in bigTempArray) if(!af.type) { [downloadsArray addObject:af]; } } return downloadsArray; } 

If there are any other methods that may be relevant, let me know and I will gladly publish them.

I should also note that after starting the application I can add a single entity to the array, but after that the same problem arose.

+6
source share
6 answers

I think your problem is the architecture of your controllers. Try the following:

1) Configure the entire main data stack in the application delegate. Pass the associated context of the managed entity to all your view controllers as a property. This is a sample that Apple uses in many sample code examples.

2) For each table view controller, create your own NSFetchedResultsController , usually the same as a property. Use Apple Samples as a Guide.

3) Never retrieve any data from another view controller, as in the code. You cannot and should not get table data for AudioTableViewController from MusikerViewController .

It is possible and sometimes useful to have a central data object that provides data for viewing controllers. This data object cannot be a view controller. This is a blatant (and in your case fatal) violation of the MVC design pattern. Your error is probably related to this (since the MusikerViewController does not appear on the screen and may even be freed).

4) Make sure that in the datasource methods you use only the selected result controller to populate the tables and deliver the media.

+3
source

Maybe your - (void) addAudioEntityToArray: (AudioFile *) event {} method is called from the secondary stream (except for the MainUi stream), so directly reloading the table will not work.

try instead

 [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 

Hope this helps!

+5
source

Add [self.tableView reloadData] to the addAudioEntityToArray method at the end. This will force the UITableView to reload the model after each insertion.

+1
source

You set eventArray through the setter:

 [self setEventsArray:[daBank getFetchArray]]; 

Why don't you access it via getter? Perhaps you are using a different instance of the array

self.eventsArray or [self eventsArray]

0
source

I suggest using fetchresultscontroller, I used arrays before, but much better with FRC.

0
source

In your addAudioEntityToArray method addAudioEntityToArray your addAudioEntityToArray call will add a new event to the array's END , not to the beginning.

For this, the indexPath you need to send to insertRowsAtIndexPaths is: for example [NSIndexPath indexPathForRow:[MusikerViewController recordingsArray].count-1 inSection:0]

0
source

Source: https://habr.com/ru/post/950600/


All Articles