UITableView不更新 [英] UITableView not updating

查看:112
本文介绍了UITableView不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Core Data模型和UITableViewController表视图。我的模型似乎工作相当不错,但我的表视图不更新,当我添加一个实体到我的模型。我相信我的模型是工作的原因是,当我添加一个实体没有显示在视图中的运行时,但是如果我剪切任务,然后启动它,新的,突然之前创建的实体显示在表视图中。

I'm using a Core Data model and a UITableViewController table view. My model seems to be working quite well however my table view is not updating when I add an entity to my model. The reason I believe my model is working is because when I add an entity nothing shows up in the view during run time, however if I cut the task then start it up new, suddenly the entity I previously created shows up in the table view.

这是我的表视图控制器 - AudioTableViewController.h

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

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];
    }
}

...更多方法

这是我的银行类的一部分,可能是相关的
Bank.h

Here is part of my Bank class that might be relevant 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

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

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 more methods that might be relevant, let me know and I will happily post them.

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

I should also mention that, I can add a single entity to the array after I launch the app, but after that its the same problem.

推荐答案

我认为你的问题是你的视图控制器的架构。请尝试以下操作:

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

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

1) Set up all the core data stack in the app delegate. Pass the associated managed object context to all your view controllers as a property. That is the pattern Apple uses in many of its sample code examples.

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

2) For each table view controller, create its own NSFetchedResultsController, normally also as a property. Use the Apple samples as a guide.

3)从不从其他视图控制器获取任何数据,就像在代码中一样。您不能也不应该从 MusikerViewController 中获取 AudioTableViewController 的表数据。

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

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

It is possible and sometimes useful to have a central data object that provides data to view controllers. You cannot have this data object be a view controller. This is a blatant (and in your case fatal) violation of the MVC design pattern. Your error most likely stems from that (because MusikerViewController is not on screen and may even be deallocated).

4 )确保在您的数据源方法中,您只使用抓取结果控制器来填充表格和传送媒体。

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

这篇关于UITableView不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆