6

我正在使用核心数据模型和 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 课程的一部分,可能与 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

银行.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;

}

播放器.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

播放器.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;
}

如果还有其他可能相关的方法,请告诉我,我会很乐意发布它们。

我还应该提到,我可以在启动应用程序后将单个实体添加到数组中,但之后会出现同样的问题。

4

6 回答 6

5

可能是您的 - (void)addAudioEntityToArray:(AudioFile *)event {} 方法是从辅助线程(MainUi 线程除外)调用的,因此直接重新加载表将不起作用。

试试吧

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

希望能帮助到你!!

于 2013-07-30T07:31:14.267 回答
3

我认为你的问题是你的视图控制器的架构。尝试这个:

1)在应用程序委托中设置所有核心数据堆栈。将关联的托管对象上下文作为属性传递给所有视图控制器。这是 Apple 在其许多示例代码示例中使用的模式。

2)对于每个表视图控制器,创建自己的 NSFetchedResultsController,通常也作为属性。使用 Apple 示例作为指南。

3)永远不要像在代码中那样从另一个视图控制器获取任何数据。您不能也不应该AudioTableViewControllerMusikerViewController.

拥有一个为视图控制器提供数据的中央数据对象是可能的,有时也很有用。你不能让这个数据对象成为一个视图控制器。这是对 MVC 设计模式的公然(在您的情况下是致命的)违反。您的错误很可能源于此(因为MusikerViewController不在屏幕上,甚至可能被释放)。

4) 确保在您的datasource方法中使用获取的结果控制器来填充表格并传递媒体。

于 2013-08-23T13:38:28.077 回答
1

[self.tableView reloadData]最后加入addAudioEntityToArray方法。这将强制 UITableView 在每次插入后从模型中重新加载。

于 2013-08-26T19:56:37.553 回答
0

您正在通过 setter 设置 eventsArray:

[self setEventsArray:[daBank getFetchArray]];

为什么不通过 getter 访问它?您可能正在使用另一个数组实例

self.eventsArray或者[self eventsArray]

于 2013-07-30T07:29:17.493 回答
0

我建议使用 fetchresultscontroller,我之前使用过数组,但使用 FRC 会更好。

于 2013-08-10T09:25:26.647 回答
0

在您的addAudioEntityToArray方法中,您的调用addObject会将新事件添加到数组的END,而不是开头。

因此,您需要发送到的 indexPathinsertRowsAtIndexPaths是:like[NSIndexPath indexPathForRow:[MusikerViewController recordingsArray].count-1 inSection:0]

于 2013-08-28T11:09:04.653 回答