我正在使用Core Data模型和UITableViewController表视图.我的模型似乎工作得很好,但是当我向模型添加实体时,我的表视图没有更新.我相信我的模型正在工作的原因是因为当我添加一个实体时,在运行时没有任何内容显示在视图中,但是如果我剪切任务然后启动它,那么我之前创建的实体突然显示在表视图中.
这是我的表视图控制器 – 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(实现文件)
#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];
}
}
…更多方法
以下是我的银行课程中可能相关的部分内容
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's 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;
}
最后但并非最不重要的,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;
}
如果有更多可能相关的方法,请告诉我,我会很乐意发布它们.
我还应该提一下,我可以在启动应用程序后向阵列添加单个实体,但之后会出现同样的问题.
解决方法
我认为您的问题是视图控制器的体系结构.试试这个:
1)在app delegate中设置所有核心数据堆栈.将关联的托管对象上下文作为属性传递给所有视图控制器.这就是Apple在许多示例代码示例中使用的模式.
2)对于每个表视图控制器,创建自己的NSFetchedResultsController,通常也作为属性.使用Apple样本作为指南.
3)永远不要像在代码中那样从其他视图控制器中获取任何数据.您不能也不应该从MusikerViewController获取AudioTableViewController的表数据.
拥有一个为查看控制器提供数据的中央数据对象是可能的,有时也是有用的.您不能将此数据对象作为视图控制器.这是对MVC设计模式的公然(并且在您的情况下是致命的)违反.您的错误很可能源于此(因为MusikerViewController不在屏幕上,甚至可能被释放).
4)确保在数据源方法中仅使用获取的结果控制器来填充表并传递媒体.