15

現在、Core Data を使用して Iphone アプリケーションを作成していEXC_BAD_ACCESSますが、[managedObjectContext save:&&error] コード行でエラーが発生します。このクラッシュは、特定のフィールドを変更した後にのみ発生します。より具体的には、エンティティには 2 つの文字列フィールド (約 10 フィールドのうち) があり、モーダル ビュー コントローラー (テキスト エディターなど) の戻り値から値を取得します。クラッシュは、これらのフィールドが編集された後にのみ発生し、最初に値を入力すると正常に機能します。

文字列だけのフォーマットコンストラクターを持つ文字列を持っている理由は、構造をコピーしようとしていたからです...それが自動的に行われるかどうかわかりませんか? これらの文字列からの保持/解放メッセージ (これら 2 つはモーダル ビュー コントローラーからのもの) と考えられ、モーダル ビュー コントローラーまたは何かの破棄時に解放されていました。それでもうまくいかないので、そうではないと思います。

クラッシュしているコードセクションは次のとおりです。

[編集]

        - (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex:    (NSInteger)buttonIndex
      switch(buttonIndex) {
              case 0: {
                if(message == nil) {
                  message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext];
                }
                message.toString = txtTo.text;
                message.fromString = txtFrom.text;
                message.subjectString = txtSubject.text;
                message.backgroundColor = [NSNumber numberWithInt:[bgColor intValue]];
                message.textArray = [NSString stringWithFormat:@"%@", stringTextArray];
                message.htmlString = [NSString stringWithFormat:@"%@", stringHTML];
                message.timeStamp = [NSDate date];
                message.statusCode = [NSNumber numberWithInt:0];
                NSError *error = nil;
                if (![message.managedObjectContext save:&error]) {
                    abort();
                }   
                break;
               }
              case 1: {
             break;
              }
      }
      if(buttonIndex != modalView.cancelButtonIndex) {
      [webViewBody loadHTMLString:@"<html><head></head><body></body></html>" baseURL:[NSURL URLWithString:@""]];
      [self.navigationController popToRootViewControllerAnimated:YES];
}

}

そして、ここにクラッシュログがあります:

例外の種類: EXC_BAD_ACCESS (SIGBUS)
例外コード: 0x00000015 の KERN_PROTECTION_FAILURE
クラッシュしたスレッド: 0

スレッド 0 がクラッシュしました:
0 libobjc.A.dylib 0x30011940 objc_msgSend + 20
1 CoreData 0x367f7d3e -[NSKnownKeysDictionary1 dealloc] + 82
2 CoreData 0x367f7cda -[NSKnownKeysDictionary1 リリース] + 34
3 CoreData 0x3687eec4 -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] + 40
4 CoreData 0x36821030 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] + 16
5 CoreData 0x368205f2 -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] + 958
6 CoreData 0x368133bc -[NSManagedObjectContext 保存:] + 412
7 Decome 0x0001fdd6 -[CreateMessageViewController actionSheet:clickedButtonAtIndex:] (CreateMessageViewController.m:163)
8 UIKit 0x30a6cbd8 -[UIActionSheet(プライベート) _buttonClicked:] + 256
9 CoreFoundation 0x30256dd4 -[NSObject performSelector:withObject:withObject:] + 20
10 UIKit 0x3096e0d0 -[UIApplication sendAction:to:from:forEvent:] + 128
11 UIKit 0x3096e038 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
12 UIKit 0x3096e000 -[UIControl sendAction:to:forEvent:] + 44
13 UIKit 0x3096dc58 -[UIControl(内部) _sendActionsForEvents:withEvent:] + 528
14 UIKit 0x309a6e9c -[UIControl touchesEnded:withEvent:] + 452
15 UIKit 0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520
16 UIKit 0x309a5464 -[UIWindow sendEvent:] + 108
17 UIKit 0x30936e3c -[UIApplication sendEvent:] + 400

どんな助けでも大歓迎です、ありがとう。

更新: また、プログラムがクラッシュしても、バックアップを開くと、データは正しく保存されています。したがって、EXC_BAD_ACCESSは、保存が少なくとも永続ストアに保存するのに十分な距離になった後に発生する必要があります。

保存行をコメントアウトすると、コードが正常に実行されるようになりました。しかし、閉じて終了した後は保存されません。ルート ビュー コントローラーの willAppear 関数で保存行を実行すると、同じ EXC_BAD_ACCESS エラーがスローされます。私が得たバックトレースを行う場合、コンソールは EXC_BAD_ACCESS 以外は何も言いません:

#0 0x30011940 in objc_msgSend ()
#1 0x367f7d44 in -[NSKnownKeysDictionary1 dealloc] ()
#2 0x367f7ce0 in -[NSKnownKeysDictionary1 リリース] ()
#3 0x3687eeca in -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] ()
#4 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] () の 0x36821036
#5 0x368205f8 in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] ()
#6 0x368133c2 in -[NSManagedObjectContext save:] ()
#7 0x0000314e in -[RootViewController viewWillAppear:] (self=0x11b560, _cmd=0x3014ecac, animation=1 '\001') at /Users/inckbmj/Desktop/iphone/Decome/Classes/RootViewController.m:85

申し訳ありませんが、以前はコードが適切にフォーマットされていませんでした。このView Controllerが新しい「メッセージ」でない場合に作成されると、次のようにfetchedResultsControllerから取得されたメッセージオブジェクトが渡されます。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MailMessage *aMessage = (MailMessage *)[fetchedResultsController objectAtIndexPath:indexPath];
    [messageView loadMessage:aMessage viewOnly:NO usingTemplate:NO];
    messageView.managedObjectContext = self.managedObjectContext;
    [self.navigationController pushViewController:messageView animated:YES]; 
}

(最初のコード セットは、messageView のクラスである MessageViewController.m ファイルからのものです)

EditorViewController をモーダル ビューとして表示してから戻った場合にのみクラッシュします。textArray と htmlString の行 (モーダル ビューが影響する唯一のもの) を次のように変更しても、

message.textArray = @"HELLO";
message.htmlString = @"HELLO";

それはまだクラッシュします。ただし、両方の行をコメントアウトすると、クラッシュしません。

そのため、モーダル ビューを表示してから NSOManagedObject の textArray または htmlString フィールドを編集しようとするとクラッシュするようです...

これが私がビューを提示する場所です:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event {
    if(!viewOnly) {
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView: txtTo];
    location = [touch locationInView: webViewBody];
        if(CGRectContainsPoint(webViewBody.bounds, location)) {
            [editor loadTextArrayString:stringTextArray];
            [self presentModalViewController:editor animated:YES];
        }
    }
}

そして、私はそれを却下します:

-(void)returnWithTextArray:(NSString *)arrayString HTML:(NSString *)html bgColor:(NSNumber *)numColor {
    [self dismissModalViewControllerAnimated:YES];
    self.stringTextArray = [NSString stringWithFormat:@"%@", arrayString];
    self.stringHTML = [NSString stringWithFormat:@"%@", html];
    self.bgColor = [NSNumber numberWithInt:[numColor intValue]];
    [webViewBody loadHTMLString:self.stringHTML baseURL:[NSURL URLWithString:@""]];
}
4

7 に答える 7

23

管理対象オブジェクトへの変更 (挿入、更新、削除) が保留されている限り、コンテキストから管理対象オブジェクトへのアクセスを保持することが保証されます。save: を呼び出すとすぐに、管理対象オブジェクトへの参照が失われる可能性があります。

setRetainsRegisteredObjects:YES を設定するとエラーが発生しなくなりましたが、管理対象オブジェクトの有効期間を管理対象オブジェクト コンテキストの有効期間に依存するように設定しているため、メモリ管理の問題が発生している可能性があります。アプリ全体でコンテキストを渡している場合、オブジェクト階層が大きい場合、これはかなり大きくなる可能性があります。

詳細については、こちらの Apple ドキュメントを参照してください: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/MO_Lifecycle.html

于 2010-12-02T02:24:15.670 に答える
10

実際の根本原因に対処しているかどうかはわかりませんが、問題は解決しました。次の行を追加すると、エラーは解消されました。

[managedObjectContext setRetainsRegisteredObjects:YES];

managedObjectContext を作成する場所へ。だから私はそれが保持数に関係していたと思います。モーダルビューが表示されたときに、インスタンス変数が部分的または一時的に解放されるのではないかと思いますか? 知らない。いずれにせよ、このエラーは解消され、プログラムは正常に動作するようになりました。

于 2009-08-10T05:58:00.303 に答える
4

同じ問題を抱えている他の人を助け、上記のSteffの応答を強化するために、このエラーの考えられる原因は、NSManagedObjectを解放しようとしていることです。

于 2010-10-11T11:32:20.573 に答える
0

私はこれがオールディーズであることを知っていますが、私は同じ問題を抱えていたので、問題をどのように解決したかについてタペンスを追加すると思いました、私の原因はモーダルビュー内の管理対象オブジェクトを手動で解放したことです、解放呼び出しを削除しました、そしてすべてが正常に動作している:)ドキュメントによると、コンテキストがすべての処理を行うため、とにかく手動で管理対象オブジェクトを解放しようとしないでください。それはとにかく私の経験です、過剰にリリースされた値のためにあなたのコードを検索してください。

于 2010-08-10T13:26:30.020 に答える
0

オブジェクトがフェッチされていることを確認することで同様の問題を解決したので、上記の例では次のようになります。

if ( message == nil ) {
    message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext];
} else {
    NSError *error = nil;
    message = (MailMessage *)[managedObjectContext existingObjectWithID:[message objectID] error:&error];
}
于 2012-12-19T16:00:18.603 に答える
0

FRC キャッシュを nil に設定する必要があります

于 2010-09-02T21:55:58.417 に答える
0

iPhone シミュレーターのコンテンツと設定をリセットすることで解決された、i​​Phone 上の CoreData に関する多くのおかしな動作を見てきました。

于 2009-08-05T14:43:24.377 に答える