从核心数据中检索实体:打印属性给我 incomplete/unwanted 结果?
Retrieving Entities from Core Data: Printing properties gives me incomplete/unwanted results?
我最近决定将所有应用程序数据从 plist 移动到 Core Data。这非常简单。我有一个带有几个属性的 class 我会阅读我所有的 plist 信息以使用字典。这是通过创建一个具有完全相同属性的实体来模仿的。然后我将 plist 信息加载到数组中,并解析它们,将新实体写入并保存到核心数据中。
听起来不错吧?好吧,我是这么想的。但是,现在我正在重新阅读所有内容,我注意到了一些问题。
首先,当我继续尝试打印对象的属性时,如下所示:
for (CXStellarObject *obj in self.starsArray)
{
NSLog(@"Type: %@\n Language: %@\n Name: %@\n ImageName: %@\n Description: %@\n",obj.type,obj.language.label,obj.name,obj.imageName,obj.description);
}
我明白了:
Type: star
Language: (null)
Name: Sirius
ImageName:
Description: <CXStellarObject: 0x7fbb0a58d5d0> (entity: CXStellarObject; id: 0xd000000000140000 <x-coredata://9E3F584C-3214-4A6A-B55A-B63D066A152B/CXStellarObject/p5> ; data: {
descriptor = "The brighest star visible from Earth, Sirius (Also known as Sirius A, or the Dog Star), is a bright white dwarf. It is part of the Canis Major Constellation. It is approximately 8.6 light years from o";
imageName = "";
language = "0xd000000000040002 <x-coredata://9E3F584C-3214-4A6A-B55A-B63D066A152B/CXLocalizationAsset/p1>";
name = Sirius;
type = star;
})
一方面,我的描述还不完整。它在 "from o" 处中断,而实际上它在 plist 中持续的时间更长。接下来,在打印结果的底部重复名称和类型。我不知道他们为什么在那里。
最后,结果数据两侧的所有这些地址和其他垃圾是什么?我不想要那里,它是怎么到那里的?
您可能需要了解我在这里进行的操作,所以我将向您展示所涉及的实体:
以下是我将所有这些对象写入 Core Data 的方式:
-(void)writeAllArraysToCoreData
{
NSArray *starsArray = [self starsArray];
NSArray *planetsArray = [self planetsArray];
NSArray *moonsArray = [self moonsArray];
NSArray *allData = @[starsArray,planetsArray,moonsArray];
for (NSArray *array in allData)
{
for (NSDictionary *dict in array)
{
[self archieveCXStellarObjectWithLanguage:[dict valueForKey:@"Language"] Type:[dict valueForKey:@"Type"] Name:[dict valueForKey:@"Name"] ImageName:[dict valueForKey:@"ImageName"] Descriptor:[dict valueForKey:@"Description"]];
}
}
}
最后,我定义的这里调用的方法:
-(void)archieveCXStellarObjectWithLanguage:(NSString *)languageCode Type:(NSString *)type Name:(NSString *)name ImageName:(NSString *)imageName Descriptor:(NSString *)descriptor
{
CXStellarObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"CXStellarObject" inManagedObjectContext:self.managedObjectContext];
[object setLanguage:[self.supportedLanguageAssets valueForKey:languageCode]];
[object setType:type];
[object setName:name];
[object setImageName:imageName];
[object setDescriptor:descriptor];
// Add New Object to All Objects Array
[self.allStoredObjects addObject:object];
// Save Changes
[self saveContext];
}
最后是我是如何提取它们的,哪里有点不对劲(别担心,这不是一个复杂的方法)
-(void)loadData
{
if (!self.allStoredObjects)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CXStellarObject" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchResults = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (!fetchResults)
{
[NSException raise:@"Fetch Failed!" format:@"Reason: %@",[error localizedDescription]];
}
[self setAllStoredObjects:[NSMutableArray arrayWithArray:fetchResults]];
// Filter Arrays
NSPredicate *starPredicate = [NSPredicate predicateWithFormat:@"SELF.type == 'star'"];
[self setStarsArray:[fetchResults filteredArrayUsingPredicate:starPredicate]];
for (CXStellarObject *obj in self.starsArray)
{
NSLog(@"Type: %@\n Language: %@\n Name: %@\n ImageName: %@\n Description: %@\n",obj.type,nil,obj.name,obj.imageName,obj.description);
}
}
}
就是这样,感谢您花时间走到这一步。如果您需要我提供更多信息,请发表评论,我会尽快将其放入。
我建议调查核心数据 "faults"。每当您在描述中看到这样的引用时,那是因为该对象尚未在内存中,只有该对象的存根。只要你触摸对象,Core Data 就会自动将它拉入内存,然后完整的值就会可见。
此外,长描述调用被剪辑是很常见的。如果您想查看完整值,请在调试器中捕获它并通过 po
.
调用它
假设您的 CXStellarObject 对象是 NSManagedObject 的自定义子类,您需要覆盖该对象的描述方法并将其写入有关您的托管对象的 return 格式信息。
像这样:
-(NSString *) 描述;
{
NSMutableString *result = [[NSMutableString alloc] init];
[result appendFormat: @" descriptor = %@\n", self.descriptor];
[result appendFormat: @" imageName = %@\n", imageName];
//等等...
}
我最近决定将所有应用程序数据从 plist 移动到 Core Data。这非常简单。我有一个带有几个属性的 class 我会阅读我所有的 plist 信息以使用字典。这是通过创建一个具有完全相同属性的实体来模仿的。然后我将 plist 信息加载到数组中,并解析它们,将新实体写入并保存到核心数据中。
听起来不错吧?好吧,我是这么想的。但是,现在我正在重新阅读所有内容,我注意到了一些问题。
首先,当我继续尝试打印对象的属性时,如下所示:
for (CXStellarObject *obj in self.starsArray)
{
NSLog(@"Type: %@\n Language: %@\n Name: %@\n ImageName: %@\n Description: %@\n",obj.type,obj.language.label,obj.name,obj.imageName,obj.description);
}
我明白了:
Type: star
Language: (null)
Name: Sirius
ImageName:
Description: <CXStellarObject: 0x7fbb0a58d5d0> (entity: CXStellarObject; id: 0xd000000000140000 <x-coredata://9E3F584C-3214-4A6A-B55A-B63D066A152B/CXStellarObject/p5> ; data: {
descriptor = "The brighest star visible from Earth, Sirius (Also known as Sirius A, or the Dog Star), is a bright white dwarf. It is part of the Canis Major Constellation. It is approximately 8.6 light years from o";
imageName = "";
language = "0xd000000000040002 <x-coredata://9E3F584C-3214-4A6A-B55A-B63D066A152B/CXLocalizationAsset/p1>";
name = Sirius;
type = star;
})
一方面,我的描述还不完整。它在 "from o" 处中断,而实际上它在 plist 中持续的时间更长。接下来,在打印结果的底部重复名称和类型。我不知道他们为什么在那里。
最后,结果数据两侧的所有这些地址和其他垃圾是什么?我不想要那里,它是怎么到那里的?
您可能需要了解我在这里进行的操作,所以我将向您展示所涉及的实体:
以下是我将所有这些对象写入 Core Data 的方式:
-(void)writeAllArraysToCoreData
{
NSArray *starsArray = [self starsArray];
NSArray *planetsArray = [self planetsArray];
NSArray *moonsArray = [self moonsArray];
NSArray *allData = @[starsArray,planetsArray,moonsArray];
for (NSArray *array in allData)
{
for (NSDictionary *dict in array)
{
[self archieveCXStellarObjectWithLanguage:[dict valueForKey:@"Language"] Type:[dict valueForKey:@"Type"] Name:[dict valueForKey:@"Name"] ImageName:[dict valueForKey:@"ImageName"] Descriptor:[dict valueForKey:@"Description"]];
}
}
}
最后,我定义的这里调用的方法:
-(void)archieveCXStellarObjectWithLanguage:(NSString *)languageCode Type:(NSString *)type Name:(NSString *)name ImageName:(NSString *)imageName Descriptor:(NSString *)descriptor
{
CXStellarObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"CXStellarObject" inManagedObjectContext:self.managedObjectContext];
[object setLanguage:[self.supportedLanguageAssets valueForKey:languageCode]];
[object setType:type];
[object setName:name];
[object setImageName:imageName];
[object setDescriptor:descriptor];
// Add New Object to All Objects Array
[self.allStoredObjects addObject:object];
// Save Changes
[self saveContext];
}
最后是我是如何提取它们的,哪里有点不对劲(别担心,这不是一个复杂的方法)
-(void)loadData
{
if (!self.allStoredObjects)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CXStellarObject" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchResults = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (!fetchResults)
{
[NSException raise:@"Fetch Failed!" format:@"Reason: %@",[error localizedDescription]];
}
[self setAllStoredObjects:[NSMutableArray arrayWithArray:fetchResults]];
// Filter Arrays
NSPredicate *starPredicate = [NSPredicate predicateWithFormat:@"SELF.type == 'star'"];
[self setStarsArray:[fetchResults filteredArrayUsingPredicate:starPredicate]];
for (CXStellarObject *obj in self.starsArray)
{
NSLog(@"Type: %@\n Language: %@\n Name: %@\n ImageName: %@\n Description: %@\n",obj.type,nil,obj.name,obj.imageName,obj.description);
}
}
}
就是这样,感谢您花时间走到这一步。如果您需要我提供更多信息,请发表评论,我会尽快将其放入。
我建议调查核心数据 "faults"。每当您在描述中看到这样的引用时,那是因为该对象尚未在内存中,只有该对象的存根。只要你触摸对象,Core Data 就会自动将它拉入内存,然后完整的值就会可见。
此外,长描述调用被剪辑是很常见的。如果您想查看完整值,请在调试器中捕获它并通过 po
.
假设您的 CXStellarObject 对象是 NSManagedObject 的自定义子类,您需要覆盖该对象的描述方法并将其写入有关您的托管对象的 return 格式信息。
像这样:
-(NSString *) 描述; { NSMutableString *result = [[NSMutableString alloc] init]; [result appendFormat: @" descriptor = %@\n", self.descriptor]; [result appendFormat: @" imageName = %@\n", imageName]; //等等... }