2

プログラムの列の@sumバインディングに問題があります。

私はCoredata、NSPersistentDocumentベースのプログラムを実行しています。私はほとんどすべてをIB、データモデルの作成、NSArrayController、NSTableViewから行っています...

62個の属性(61個のNSStringと1個のNSNumber)を持つエンティティが1つだけあります。12722レコードのCSVファイルをインポートします。インポートはうまく機能し、xml、binary、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(Live Bytes)と> 1.500.00#Overallが表示されました。したがって、Interger32タイプの12722行/レジスタについて話しているので、ここで何かが間違っています。

2番目の問題は同じですが、異なる角度から再現されます。「selection」を使用する代わりに、「arrangedObjects」を使用しようとしました。この場合、CSVからインポートしているときでも問題が発生し、非常に遅くなり、最終的にクラッシュします。作成済みのファイルを開こうとするとクラッシュします。

これは私がlabel->BindingsInspector->Valueを行った方法です

>    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からarrangedObjects。@ sum.t_24_Bookingsにバインドしようとすると、プログラムがクラッシュします。

私の最初の推測は、ペン先がロードされた後、オブジェクトコントローラーのコンテンツにアクセスできないことに関連していますが、成功せずにこのような最初のフェッチを実行するという推奨事項に従いました。

- (void) awakeFromNib
{
    :
    BOOL ok = [[self out_CtEn_Transaction] fetchWithRequest:nil merge:NO error:&error];
    :

このアイデアを続けると、「実際の」完全なフェッチを作成し、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;

:

ABDocumentの実装

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

}

コメントしていただければ幸いです。解決策はありますが、理由がわかりません。

戦車、
ルイス

4

1 に答える 1

0

数日調べたところ、自分で問題を見つけました。それは簡単でした(今私が知っている):

並行して、セカンダリスレッドを作成していて、たまたま2つの異なるスレッドからデータモデルにアクセスしていました。ここStackoverflowのいくつかのQ&Aで説明されているように、それは非常に危険です。

セカンダリスレッドでセカンダリMOCを作成するいくつかの投稿で、コメント付きのソリューションを適用しました。

これで、私のコードはcoredata関連のアクションに従ってスレッドセーフになり、プログラムがクラッシュしなくなりました。

コミュニティに改めて感謝します。

ルイス

于 2012-11-30T20:27:17.233 に答える