1

Xcodeでその内容EXC_BAD_ACCESSを試したときにいつでも提供する単純なコアデータオブジェクトがあります。NSLog

管理対象オブジェクトは次のようになります。

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class ChatFriend, ChatMessage;

@interface ChatThread : NSManagedObject

@property (nonatomic, retain) NSString * threadId;
@property (nonatomic, retain) NSDate * timestamp;
@property (nonatomic, retain) NSSet *friends;
@property (nonatomic, retain) NSSet *messages;
@end

@interface ChatThread (CoreDataGeneratedAccessors)

- (void)addFriendsObject:(ChatFriend *)value;
- (void)removeFriendsObject:(ChatFriend *)value;
- (void)addFriends:(NSSet *)values;
- (void)removeFriends:(NSSet *)values;

- (void)addMessagesObject:(ChatMessage *)value;
- (void)removeMessagesObject:(ChatMessage *)value;
- (void)addMessages:(NSSet *)values;
- (void)removeMessages:(NSSet *)values;

@end

これは.mファイルです:

#import "ChatThread.h"
#import "ChatFriend.h"
#import "ChatMessage.h"


@implementation ChatThread

@dynamic threadId;
@dynamic timestamp;
@dynamic friends;
@dynamic messages;

- (NSString*) description
{

    /* This can print out the contents of self.messages correctly
    for(ChatMessage *message in self.messages)
    {
        Log(@"ChatMessage - %@", message);
    }
    */

    // using %@ to print out self.messages directly, will fail:
    return [NSString stringWithFormat:@"ChatThread - threadId:%@, messages count:%d, messages:%@", self.threadId, self.messages.count, self.messages];
}

@end

stringWithFormat行のself.messagesの内容を印刷しようとすると、EXC_BAD_ACCESS発生することに気づきました。self.messagesを削除すると、印刷するだけself.messages.countで機能します。手動でforループを実行してメッセージ内の各メッセージを出力するNSSetと、それは機能し、そこにいくつかの値があることを証明します。

では、なぜself.messagesを直接印刷するとトリガーされるのEXC_BAD_ACCESSでしょうか。

4

1 に答える 1

4

descriptionNSManagedObject でのオーバーライドに関しては、ドキュメントは非常に明示的です。

フォルト時に次のメソッドを起動することなく安全に呼び出すことができます。 、isUpdated、isDeleted、faultingState、および isFault。isEqual と hash はフォールトを発生させないため、通常、マネージド オブジェクトはフォールトを発生させずにコレクションに配置できます。ただし、コレクション オブジェクトでキー値コーディング メソッドを呼び出すと、管理対象オブジェクトで valueForKey: が呼び出され、フォールトが発生する可能性があることに注意してください。

description メソッドはフォールトを発生させませんが、オブジェクトの永続プロパティにアクセスするカスタムの説明メソッドを実装すると、フォールトが発生します。このように説明を上書きすることは強くお勧めしません。

最後の段落の警告に違反したようです。NSManagedObjectContext がオブジェクトをフォールトとして返さないようにするかvalueForKey:、明示的にフォールトを発生させ、その説明にアクセスする前に結果のプロパティをロードするために使用します。エラーが発生したオブジェクト自体が起動すると、未定義の動作が発生します。

于 2013-03-10T10:24:14.627 に答える