2013-07-20 27 views
0

我使用的是源自Apple的DateSectionTitles示例代碼的代碼。在我的班級Appointment我與Location有關係。此外,我生成一個由UITableViewController使用的部分標識符。NSManagedObject的@synthesize屬性在修改關係後仍然存在錯誤

@class Location; 

@interface Appointment : NSManagedObject 

@property (nonatomic, retain) NSDate * begin; 
@property (nonatomic, retain) NSDate * end; 
@property (nonatomic, retain) Location * location; 

@property (nonatomic, retain) NSString *sectionIdentifier; 
@property (nonatomic, retain) NSString *primitiveSectionIdentifier; 

@end 



@implementation Appointment 

@synthesize begin = _begin; 
@dynamic end; 
@dynamic location; 
@dynamic primitiveSectionIdentifier; 
@dynamic sectionIdentifier; 

#pragma mark - 
#pragma mark Transient properties 

- (NSString *)sectionIdentifier { 

    // Create and cache the section identifier on demand. 

    [self willAccessValueForKey:@"sectionIdentifier"]; 
    NSString *tmp = [self primitiveSectionIdentifier]; 
    [self didAccessValueForKey:@"sectionIdentifier"]; 

    if (!tmp) { 
     /* 
     Sections are organized by month and year. Create the section identifier as a string representing the number (year * 1000) + month; this way they will be correctly ordered chronologically regardless of the actual name of the month. 
     */ 
     NSCalendar *calendar = [NSCalendar currentCalendar]; 

     NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) 
                fromDate:[self begin]]; 
     tmp = [NSString stringWithFormat:@"%d", ([components year] * 10000) + [components month] * 100 + [components day]]; 
     [self setPrimitiveSectionIdentifier:tmp]; 
    } 

    return tmp; 
} 


#pragma mark - 
#pragma mark Begin setter 

- (void)setBegin:(NSDate *)begin 
{ 
    // If the time stamp changes, the section identifier become invalid. 
    [self willChangeValueForKey:@"begin"]; 
    [self willChangeValueForKey:@"primitiveSectionIdentifier"]; 

    _begin = begin; 
    [self setPrimitiveSectionIdentifier:nil]; 

    [self didChangeValueForKey:@"begin"]; 
    [self didChangeValueForKey:@"primitiveSectionIdentifier"]; 
} 

@end 

問題:改變位置後的數據撐故障。 之前修改location物體看起來是這樣的:

<Appointment: 0x837d570> (entity: Appointment; id: 0x837c900 <x-coredata://83B2187C-00B3-4029-B4C5-4EB69C18FC59/Appointment/p1> ; data: { 
    begin = "2013-07-27 16:00:00 +0000"; 
    end = "2013-07-27 18:00:00 +0000"; 
    location = "0x837e6c0 <x-coredata://83B2187C-00B3-4029-B4C5-4EB69C18FC59/Location/p1>"; 
}) 

改變屬性location後:

<Appointment: 0x9b7b1f0> (entity: Appointment; id: 0x9b7ab50 <x-coredata://83B2187C-00B3-4029-B4C5-4EB69C18FC59/Appointment/p1> ; data: <fault>) 

如果我從產生段標識和使用@dynamic代替@synthesized財產的放棄它仍然有效。這是什麼原因以及如何克服這個問題?

+0

「約會」與「ReservationModel」相同嗎? –

+0

對不起,由於簡化我的錯。 – Norbert

+0

你是什麼意思的「改變後的位置數據保持故障」?故障不是一個錯誤。什麼不工作? - 還要注意,被管理對象的屬性不是由實例變量實現的。 '@synthesize begin = _begin;'和'_begin = begin;'不正確。 –

回答

0

感謝Martin R誰指出我在正確的方向我發現我的代碼中的問題。

什麼我不知道的是,核心數據自動生成額外原始屬性你的事實:給出一個屬性名字,核心數據 自動生成的firstName實體

例如, setFirstName:,primitiveFirstName, 和setPrimitiveFirstName :.核心數據即使對於由NSManagedObject表示的實體 也這樣做。爲了抑制編譯器警告,當你 調用這些方法,你應該使用Objective-C 2.0宣告 屬性功能,如「宣言」。

Source

說我沒」事實意識到這一點,導致我以錯誤的方式採用示例代碼。它對我的工作方式是:

@class Location; 

@interface Appointment : NSManagedObject 

@property (nonatomic, retain) NSDate * primitiveBegin; 
@property (nonatomic, retain) NSDate * begin; 

@property (nonatomic, retain) NSDate * end; 
@property (nonatomic, retain) Location * location; 

@property (nonatomic, retain) NSString *sectionIdentifier; 
@property (nonatomic, retain) NSString *primitiveSectionIdentifier; 

@end 




@implementation Appointment 

@dynamic primitiveBegin; 
@dynamic begin; 

@dynamic end; 
@dynamic location; 

@dynamic primitiveSectionIdentifier; 
@dynamic sectionIdentifier; 


#pragma mark - 
#pragma mark Transient properties 

- (NSString *)sectionIdentifier { 

    // Create and cache the section identifier on demand. 

    [self willAccessValueForKey:@"sectionIdentifier"]; 
    NSString *tmp = [self primitiveSectionIdentifier]; 
    [self didAccessValueForKey:@"sectionIdentifier"]; 

    if (!tmp) { 
     /* 
     Sections are organized by month and year. Create the section identifier as a string representing the number (year * 1000) + month; this way they will be correctly ordered chronologically regardless of the actual name of the month. 
     */ 
     NSCalendar *calendar = [NSCalendar currentCalendar]; 

     NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) 
                fromDate:[self begin]]; 
     tmp = [NSString stringWithFormat:@"%d", ([components year] * 10000) + [components month] * 100 + [components day]]; 
     [self setPrimitiveSectionIdentifier:tmp]; 
    } 

    return tmp; 
} 


#pragma mark - 
#pragma mark Begin setter 

- (void)setBegin:(NSDate *)begin 
{ 
    // If the time stamp changes, the section identifier become invalid. 
    [self willChangeValueForKey:@"begin"]; 
    [self setPrimitiveBegin:begin]; 
    [self didChangeValueForKey:@"begin"]; 

    [self setPrimitiveSectionIdentifier:nil]; 
} 


#pragma mark - 
#pragma mark Key path dependencies 

+ (NSSet *)keyPathsForValuesAffectingSectionIdentifier 
{ 
    // If the value of timeStamp changes, the section identifier may change as well. 
    return [NSSet setWithObject:@"begin"]; 
} 

@end 
相關問題