为什么我需要不断重新加载我的数据来填充我的NSTableView?

时间:2012-05-19 01:56:11

标签: objective-c core-data nsarray nstableview

我在Objective-C工作,在我的程序中遇到了一致的问题。我有一堆NSTableViews,到目前为止,我总是不得不在我的两个函数中“重新加载”数据:numberOfRowsInTableView和用内容填充它们的那个。

例如,我的“loadData()”函数使用获取请求(使用Core Data)填充在我的.h文件中声明的数组。

我想只需要在我的“awakeFromNib”函数中访问这个loadData()函数,或者只需要更新内容。但是我发现如果我没有在两个必要的NSTableView函数的顶部添加对函数的调用,程序就会崩溃。

这开始引起问题,因为我认为在没有任何变化的情况下从Core Data文件中不断获取是非常多余的。

以下是一些代码:

- (int)numberOfRowsInTableView:(NSTableView *)aTableView {
[self loadData];

if ([aTableView isEqual:(invoicesListTable)])
{
    return (int)[fetchedInvoices count];
}}

如果我不包含[self loadData]功能,程序将崩溃。即使我在awakeFromNib函数中有[self loadData],也会发生这种情况。

为什么我的程序“不记住”fetchedInvoices数组的值?它在我的.h文件中声明如下:NSArray *fetchedInvoices;

我的“loadData”函数如下:

- (void)loadData {
NSError *error = nil;


// fetch all invoices
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Invoice"
                                          inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                    initWithKey:@"InvoiceNumber" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];


fetchedInvoices = [managedObjectContext executeFetchRequest:fetchRequest error:&error];


if (fetchedInvoices == nil) {
    NSLog(@"ERROR");
}
[fetchRequest release];
// end of invoice fetch

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:3)

由于您没有使用ARC - 我在您的代码中看到了对-release的调用 - 您必须确保对象在您需要的时间内保持不变。

特别是,-executeFetchRequest:error:返回您不拥有的数组。它的寿命是不可预测的。由于您长时间保留它,您需要保留它。如果你保留它,那么你当然也有责任在你不再需要时释放它。

确保正确管理内存(不使用ARC)的最佳方法是将其限制在-init-dealloc以及属性的设置者。因此,您应该使用正确的所有权语义(@synthesizefetchedInvoicesstrong)为retain实施或copy设置器,并使用它来设置属性,而不是直接分配实例变量。

因此,举例来说,您可以在课程@interface中添加以下内容:

@property (copy) NSArray *fetchedInvoices;

然后,在您的@implementation中,您将拥有:

@synthesize fetchedInvoices;

或者您将使用其声明所需的语义来实现setter。

然后,而不是这一行:

fetchedInvoices = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

你会这样做:

self.fetchedInvoices = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

或等效地:

[self setFetchedInvoices:[managedObjectContext executeFetchRequest:fetchRequest error:&error]];