2 つのエンティティ: UserとBuildings。
ユーザーには、建物という名前のNSSetタイプの属性があります
属性guidでNSSetからBuildingsエンティティを取得したいと考えています。
アプリケーションの最初の実行時に、データの追加は成功します。データを正しく取得して表示できます。アプリケーションが閉じられた後、GUID によって既存の建物エンティティを取得しようとすると失敗します。エンティティがないため、最初getBuildingsByGuid
は返されます。nil
関数getBuildingsByGuidを呼び出し、建物セットにエンティティがあると、アプリケーションがクラッシュします。述語を使用したフェッチが機能します。エンティティ間の関係は、1 人のユーザーと多くの建物です。
デバッグを介して命令をキャッチできません。
Userオブジェクトでは、次のカスタム メソッドがBuildingsを取得する必要があります。
- (Buildings *)getBuildingsByGuid:(NSString *)guid
{
for (Buildings *buildings in self.buildings)
{
if ([buildings.guid isEqualToString:guid])
return buildings;
}
return nil;
}
編集:私のエンティティのユーザーヘッダーには次が含まれます:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Buildings, TableBuildings;
@interface User : NSManagedObject
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * first_name;
@property (nonatomic, retain) NSString * guid_contact;
@property (nonatomic, retain) NSString * guid_user;
@property (nonatomic, retain) NSString * guid_userRole;
@property (nonatomic, retain) NSString * last_name;
@property (nonatomic, retain) NSString * password;
@property (nonatomic, retain) NSString * role_code;
@property (nonatomic, retain) NSString * role_name;
@property (nonatomic, retain) NSString * token;
@property (nonatomic, retain) NSString * type_code;
@property (nonatomic, retain) NSString * type_name;
@property (nonatomic, retain) NSSet *buildings;
@property (nonatomic, retain) NSSet *tableBuildings;
@end
@interface User (CoreDataGeneratedAccessors)
// Buildings
- (void)addBuildingsObject:(Buildings *)value;
- (void)removeBuildingsObject:(Buildings *)value;
- (void)addBuildings:(NSSet *)values;
- (void)removeBuildings:(NSSet *)values;
- (BOOL)containsBuildingsObject:(Buildings*)value;
- (Buildings *)getBuildingsByGuid:(NSString *)guid;
// TableBuildings
- (void)addTableBuildingsObject:(TableBuildings *)value;
- (void)removeTableBuildingsObject:(TableBuildings *)value;
- (void)addTableBuildings:(NSSet *)values;
- (void)removeTableBuildings:(NSSet *)values;
- (BOOL)containsTableBuildingsObject:(TableBuildings*)value;
- (TableBuildings *)getTableBuildingsByGuid:(NSString *)guid;
@end
実装ファイル:
#import "User.h"
#import "Buildings.h"
#import "TableBuildings.h"
@implementation User
@dynamic email;
@dynamic first_name;
@dynamic guid_contact;
@dynamic guid_user;
@dynamic guid_userRole;
@dynamic last_name;
@dynamic password;
@dynamic role_code;
@dynamic role_name;
@dynamic token;
@dynamic type_code;
@dynamic type_name;
@dynamic buildings;
@dynamic tableBuildings;
@end
@implementation User (CoreDataGeneratedAccessors)
#pragma mark - Buildings management methods
- (void)addBuildingsObject:(Buildings *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"buildings"] addObject:value];
[self didChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)removeBuildingsObject:(Buildings *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"buildings" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"buildings"] removeObject:value];
[self didChangeValueForKey:@"buildings" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)addBuildings:(NSSet *)values
{
[self willChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
[[self primitiveValueForKey:@"buildings"] unionSet:values];
[self didChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
}
- (void)removeBuildings:(NSSet *)values
{
[self willChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
[[self primitiveValueForKey:@"buildings"] unionSet:values];
[self didChangeValueForKey:@"buildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
}
- (BOOL) containsBuildingsObject:(Buildings*)value
{
for (Buildings *buildings in self.buildings)
{
if( [buildings.guid isEqualToString:value.guid])
return YES;
}
return NO;
}
- (Buildings *)getBuildingsByGuid:(NSString *)guid
{
for (Buildings *buildings in self.buildings)
{
if ([buildings.guid isEqualToString:guid])
return buildings;
}
return nil;
}
#pragma mark - TableBuildings management methods
- (void)addTableBuildingsObject:(TableBuildings *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"tableBuildings"] addObject:value];
[self didChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)removeTableBuildingsObject:(TableBuildings *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"tableBuildings"] removeObject:value];
[self didChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)addTableBuildings:(NSSet *)values
{
[self willChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
[[self primitiveValueForKey:@"tableBuildings"] unionSet:values];
[self didChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
}
- (void)removeTableBuildings:(NSSet *)values
{
[self willChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
[[self primitiveValueForKey:@"tableBuildings"] unionSet:values];
[self didChangeValueForKey:@"tableBuildings" withSetMutation:NSKeyValueUnionSetMutation usingObjects:values];
}
-(BOOL) containsTableBuildingsObject:(TableBuildings*)value
{
for (TableBuildings *tableBuildings in self.tableBuildings)
{
if( [tableBuildings.guid_building isEqualToString:value.guid_building])
return YES;
}
return NO;
}
- (TableBuildings *)getTableBuildingsByGuid:(NSString *)guid
{
for (TableBuildings *tableBuildings in self.tableBuildings)
{
if ([tableBuildings.guid_building isEqualToString:guid])
return tableBuildings;
}
return nil;
}
@終わり
アプリの起動時にメールとパスワードでユーザーをフェッチする場合:
user = [[DataController instance] fetchEntityOfType:object_User withPredicate:@"email = %@ AND password = %@", username, passwordMD5];
後で、建物のリストを表示したい場合は、次のように getBuildingsByGuid メソッドを呼び出します。
// buildings is parsed from json and have NSDictionary type
for (NSDictionary *building in buildings)
{
NSString *guid_building = [building safeObjectForKey:@"guid"];
// get building and check if is associated to the current user
BuildingPerUser *buildingPerUser = [[DataController instance] fetchEntityOfType:object_BuildingPerUser withPredicate:@"guid_user = %@ AND guid_building = %@", guid_user, guid_building];
//create new association if not exists
if (!buildingPerUser)
{
buildingPerUser = [[[DataController instance] newEnityOfType:object_BuildingPerUser] autorelease];
buildingPerUser.guid_user = guid_user;
buildingPerUser.guid_building = guid_building;
}
Buildings *buildingRow = [user getBuildingsByGuid:guid_building];
// create new building if not exists
if (!buildingRow)
{
buildingRow = [[[DataController instance] newEnityOfType:object_Buildings] autorelease];
buildingRow.guid = guid_building;
[user addBuildingsObject:buildingRow];
}
// update building
buildingRow.name = [building safeObjectForKey:@"name"];
buildingRow.isNew = [NSNumber numberWithBool:NO];
[delComplementBuildings addObject:guid_building];
}
私が使用する場合:
Buildings *buildingRow = [[DataController instance] fetchEntityOfType:object_Buildings withPredicate:@"guid = %@", guid_building];
...私のアプリの仕事。と:
Buildings *buildingRow = [user getBuildingsByGuid:guid_building];
.. アプリがクラッシュします。
述語フェッチの代わりにオブジェクトを使用することを好みます...
別の編集: 例外が見つかりました:建物の nsset エンティティに関する関係障害以下は建物 のリストです:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class TableBuildings, User;
@interface Buildings : NSManagedObject
@property (nonatomic, retain) NSString * guid;
@property (nonatomic, retain) NSNumber * isNew;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *tableBuildings;
@property (nonatomic, retain) User *user;
@end
@interface Buildings (CoreDataGeneratedAccessors)
- (void)addTableBuildingsObject:(TableBuildings *)value;
- (void)removeTableBuildingsObject:(TableBuildings *)value;
- (void)addTableBuildings:(NSSet *)values;
- (void)removeTableBuildings:(NSSet *)values;
@end
#import "Buildings.h"
#import "TableBuildings.h"
#import "User.h"
@implementation Buildings
@dynamic guid;
@dynamic isNew;
@dynamic name;
@dynamic tableBuildings;
@dynamic user;
@end
建物アクセサーはまだ実装されていません。
問題が解決しました。ユーザーの初期化ミスでした。解決策: ユーザーのプロパティを使用します。