2013-03-10 43 views
1

我有一個簡單的核心數據對象,只要我嘗試在Xcode中嘗試NSLog的內容,就會給我一個EXC_BAD_ACCESSEXC_BAD_ACCESS當試圖在被管理對象中NSLOG NSSET時

管理對象是這樣的:

#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 

我發現,如果我試圖打印出self.messages的內容在stringWithFormat線,EXC_BAD_ACCESS會發生。如果我刪除self.messages,只打印self.messages.count,它的工作原理。如果我手動執行一個for循環打印出消息NSSet中的每條消息,它就會起作用,並證明那裏有一些值。

那麼,爲什麼直接打印self.messages會觸發EXC_BAD_ACCESS

+0

奇怪。 self.messages是否會拋出此異常,即使經過循環並單獨打印每個成員之後? – 2013-03-10 10:34:34

+0

當你打印[self.messages描述]時有什麼不同? – 2013-03-10 10:35:23

+0

我不知道它解釋了這個問題,但如果這是一個OS X應用程序,那麼'count'將返回一個64位的'NSUInteger',並且應該使用'%ld'而不是'%d'來打印。 – 2013-03-10 10:45:13

回答

4

該文檔是非常明確的,當談到覆蓋description在NSManagedObject:

你可以安全地調用上的故障以下方法,而它導致火災::,的isEqual哈希,父類,類, self,isProxy,isKindOfClass:,isMemberOfClass:,conformsToProtocol:,respondsToSelector:,description,managedObjectContext,entity,objectID,isInserted,isUpdated,isDeleted,faultingState和isFault。由於isEqual和hash不會導致錯誤觸發,因此通常可以將託管對象置於集合中,而不會觸發錯誤。但是請注意,調用集合對象上的鍵值編碼方法可能會導致在受管對象上調用valueForKey:,從而引發錯誤。

儘管描述方法不會引發錯誤,但如果實現訪問對象持久屬性的自定義描述方法,則會引發錯誤。強烈建議您不要以這種方式重寫描述。

您似乎違反了最後一段中的警告。使您的NSManagedObjectContext不會將對象作爲錯誤返回,或者使用valueForKey:顯式觸發錯誤並在嘗試訪問它的描述之前加載結果屬性。引發自身故障的對象會導致未定義的行爲。

+2

https://developer.apple。com/library/mac /#documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html#// apple_ref/occ/cl/NSSet說這是。 – mrueg 2013-03-10 10:26:25

+0

嗨,對不起,我仍然是CoreData中的新成員,「造成故障觸發」是什麼意思呢?我猜這意味着「導致託管對象從持久存儲加載到內存中?」 – mkto 2013-03-10 10:56:08

+0

是的。而當您嘗試使用對象格式說明符時,它實際上是您的第一個導致錯誤加載自身的字符串屬性。感謝 – CodaFi 2013-03-10 10:57:15