我的程序中的列的@sum 绑定有问题:
我正在做一个基于 Coredata、NSPersistentDocument 的程序。我主要从 IB 做所有事情,创建数据模型、NSArrayController 和 NSTableView ......
我只有 1 个具有 62 个属性(61 个 NSString 和 1 个 NSNumber)的实体。我导入了一个包含 12722 条记录的 CSV 文件。导入效果很好,可以保存到 xml、二进制、sqlite...我已经仔细检查了整个过程是否完美。可以保存/加载。一切都在那里。
我遇到的问题:我创建了一个标签,我将其绑定到具有 NSNumber 属性的列的@sum。我就是这样做的
> label->Bindings Inspector->Value
> Bind to: My_Entity_NSArrayController
> Controller Key: selection
> Model Key Path: @sum.myNumericAttribute
当我运行程序时,单击导入,选择所有行,@sum 运行良好。它很快,但是这是第一个问题:一旦我保存文件(尝试了所有... binary/xml/sqlite)并稍后加载它并尝试再次选择全部,程序崩溃而没有错误。
通过“配置文件”-> 分配尝试。我注意到:
- 我没有内存泄漏
- 从磁盘加载然后全选时:速度非常慢。5 分钟后还没有完成(我停止了它),我看到了 +45MB 的 CFNumber(实时字节)和 >1.500.00#Overall。所以,这里出了点问题,因为我说的是 12722 行/Interger32 类型的寄存器。
第二个问题是相同的,但从不同的角度再现。我没有使用“选择”,而是尝试使用“arrangedObjects”。在这种情况下,即使从 CSV 导入也会出现问题,它变得非常缓慢,最终崩溃。尝试打开已经创建的文件也会崩溃。
这就是我做标签->绑定检查器->值的方式
> label->Bindings Inspector->Value
> Bind to: My_Entity_NSArrayController
> Controller Key: arrangedObjects
> Model Key Path: @sum.myNumericAttribute
您能否帮助我了解要查找的内容或可以帮助我找到问题所在的想法?
非常感谢。
路易斯
---- 更多研究后的新编辑 ----
我找到了一个我不理解的解决方法,请评论/回答非常感谢。
我的程序使用 Coredata (SQLite)、NSPersistentDocument、NSTableView 和 NSArrayController。我想让一个工作的 NSTextField 绑定到 @sum 集合操作
问题:只要我打开一个填充了 SQLite DB 的现有文档,并尝试从 NSWindowController 绑定到排列对象。@sum.t_24_Bookings,程序就会崩溃。
我最初的猜测与加载 nib 后无法访问对象控制器的内容有关,但是我遵循了执行第一次 Fetch 的建议,但没有成功:
- (void) awakeFromNib
{
:
BOOL ok = [[self out_CtEn_Transaction] fetchWithRequest:nil merge:NO error:&error];
:
继续这个想法,我发现如果我创建一个“真正的”完整 Fetch + 我从 Document 子类执行 @sum 访问,那么它就可以工作。
这是我为了使解决方法起作用而放置的带有注释的代码。
ABDocument 接口(一个 NSPersistentDocument 子类)
@interface ABDocument : NSPersistentDocument {
BOOL ivNewDocument;
NSArray *ivFetchedTransactions;
NSNumber *ivTotalBookings;
}
@property (nonatomic, getter=isNewDocument) BOOL newDocument;
@property (nonatomic, retain) NSArray *fetchedTransactions;
@property (nonatomic, retain) NSNumber *totalBookings;
:
AB文档实施
#import "ABDocument.h"
#import "ABWindowController.h"
@implementation ABDocument
@synthesize newDocument = ivNewDocument;
@synthesize totalBookings = ivTotalBookings;
@synthesize fetchedTransactions = ivFetchedTransactions;
:
/** @brief Create one instance of my custom NSWindowController subclass (ABWindowController)
*
* In my NSPersistentDocument I do override makeWindowControllers, where I create
* one instance of my custom NSWindowController subclass and use addWindowController:
* to add it to the document.
*
*/
- (void) makeWindowControllers
{
// Existing Document?
if ( ![self isNewDocument]) {
// NSLog(@"%@:%@ OPENING EXISTING DOCUMENT", [self class], NSStringFromSelector(_cmd));
// Opening existing document (also has an existing DDBB (SQLite)), so
// make sure I do perform a first complete "fetch + @sum" to void issues
// with my NIB bind's.
[self firstFetchPreventsProblems];
}
// Now I can create the Window Controller using my "MainWindow.xib".
ABWindowController *windowController = [[ABWindowController alloc] init];
[self addWindowController:windowController];
[windowController release];
}
/** @brief First complete "fetch + @sum" to void issues with my NIB bind's.
*
* Before I create the Window Controller with "MainWindow.xib" I have to perform a
* first Fetch AND also retrieve a @sum of an NSNumber column.
*
* My NIB has an NSTextField BOUND to @arrangedObjects.@sum.<property> through a NSArrayController
* If I don't call this method before the NIB is loaded, then the program will crash.
*
*/
- (void) firstFetchPreventsProblems {
// Prepare the Fetch
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Transaction"];
// 1) Perform the Fetch
NSError *error = nil;
[self setFetchedTransactions:[[self managedObjectContext ] executeFetchRequest:request error:&error]];
if ([self fetchedTransactions] == nil)
{
NSLog(@"Error while fetching\n%@",
([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
exit(1);
}
// 2) Execute Collection Operation @sum
[self setTotalBookings:[[self fetchedTransactions] valueForKeyPath:@"@sum.t_24_Bookings"]];
}
ABWindowController(加载我的NIB的控制器)
- (void)windowDidLoad
{
:
// PROGRAM CRASH HERE
// IF [self firstFetchToPreventsProblems]; is NOT CALLED
// ABDocument's "makeWindowControllers:"
[[self totalSumField] bind: @"value" toObject: [self out_CtEn_Transaction]
withKeyPath:@"arrangedObjects.@sum.t_24_Bookings" options:nil];
}
请如果你能评论真的很感激,我有一个解决方案,但我不明白为什么。
坦克,
路易斯