0

我正在使用 Objective-C 并在我的程序中遇到一个一致的问题。我有一堆 NSTableView,直到现在,我总是不得不在我的两个函数中不断地“重新加载”数据:numberOfRowsInTableView 和一个用内容填充它们的函数。

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

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

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

这是一些代码:

- (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

任何帮助,将不胜感激。

4

1 回答 1

3

因为你没有使用 ARC——我-release在你的代码中看到了调用——你必须确保对象只要你想要它们就一直存在。

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

确保正确进行内存管理(不使用 ARC)的最佳方法是将其限制在-init-dealloc和属性的设置器中。因此,您应该使用适当的所有权语义(、、或)实现或@synthesize设置器,并使用它来设置属性,而不是直接分配实例变量。fetchedInvoicesstrongretaincopy

因此,例如,您可以将以下内容放入您的班级@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]];
于 2012-05-19T09:29:33.827 回答