我是iOS-Development领域的新手,现在尝试从iOS4将现有应用更新到iOS 6.1。
从Store中获取数据以显示在NewsPageView:UIViewController
中
NewsPageView.m
#import "NewsPageView.h"
@interface NewsPageView ()
@end
@implementation NewsPageView
@synthesize newsDetailsView,
newsTableView,
newsHeaderText
;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
/*
* Get managedObjectContext and List of News over AppDelegate
*/
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
//Setting self.managedObjectContext
self.managedObjectContext = appDelegate.managedObjectContext;
// Fetching Records from the data base to show in the table
self.listOfNews = [[appDelegate getDataFromStore:self]copy];
//
NSLog(@"Data from Store in NewsPageView: %@",self.listOfNews.description);
}
尝试将数据设置/写入Context
-(void) setDataToStore
{
NSLog(@"Trying to write News in Store");
News *newNews = [NSEntityDescription insertNewObjectForEntityForName:@"News" inManagedObjectContext:self.managedObjectContext];
newNews.newsId = [[NSNumber alloc]initWithInt:508];
newNews.title = @"Some Title";
newNews.content = @"Some content";
newNews.detailsUrl = @"www.someURL.de";
newNews.date = [[NSDate alloc]init];
newNews.dateTs = [[NSNumber alloc]initWithInt:138114787];
newNews.primaryCat = [[NSNumber alloc]initWithInt:0];
//make Categorien...
NewsCategorien *cat1 = [NSEntityDescription insertNewObjectForEntityForName:@"NewsCategorien" inManagedObjectContext:self.managedObjectContext];
cat1.catId = [[NSNumber alloc]initWithInt:1];
cat1.name = @"Windows";
cat1.news = newNews;
NewsCategorien *cat2 = [NSEntityDescription insertNewObjectForEntityForName:@"NewsCategorien" inManagedObjectContext:self.managedObjectContext];
cat2.catId = [[NSNumber alloc]initWithInt:2];
cat2.name = @"Linux";
cat2.news = newNews;
NewsCategorien *cat3 = [NSEntityDescription insertNewObjectForEntityForName:@"NewsCategorien" inManagedObjectContext:self.managedObjectContext];
cat3.catId = [[NSNumber alloc]initWithInt:3];
cat3.name = @"Apple";
cat3.news = newNews;
NewsCategorien *cat5 = [NSEntityDescription insertNewObjectForEntityForName:@"NewsCategorien" inManagedObjectContext:self.managedObjectContext];
cat5.catId = [[NSNumber alloc]initWithInt:5];
cat5.name = @"Smartphone";
cat5.news = newNews;
newNews.isNews = [NSNumber numberWithBool:YES];
NSArray *catListe = [NSArray arrayWithObjects:cat1,cat2,cat3,cat5, nil];
// //saving cat by converting Cat. objects
// newNews.categories = catListe;
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
NSLog(@"Saving ok!");
}
尝试从上下文中获取数据
- (NSArray *)getDataFromStore:(id)sender
{
// initializing NSFetchRequest
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSArray *fetchedData;
//get Data für NewsTable View
if([sender isKindOfClass:[NewsPageView class]]){
//Setting Entity to be Queried
fetchRequest.entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:self.managedObjectContext];
NSError* error;
//Point of Error by debugging!!!
//return list of News
fetchedData = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
//print fetched Data
for (News *news in fetchedData) {
NSLog(@"News:%@", news.description);
}
// Returning Fetched News
return fetchedData;
}
类
News.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class NewsCategorien;
@interface News : NSManagedObject <NSCoding>
@property (nonatomic, retain) id categories;
@property (nonatomic, retain) NSString * content;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSNumber * dateTs;
@property (nonatomic, retain) NSString * detailsUrl;
@property (nonatomic, retain) NSNumber * isNews;
@property (nonatomic, retain) NSNumber * newsId;
@property (nonatomic, retain) NSNumber * primaryCat;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSSet *categorie;
//have to be implement...
//to work with NSKeyedArchiver by serialising Objects
- (void)encodeWithCoder:(NSCoder *)aCoder;
//to work with NSKeyedUnarchiver by deserialising Objects
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
@interface News (CoreDataGeneratedAccessors)
- (void)addCategorieObject:(NewsCategorien *)value;
- (void)removeCategorieObject:(NewsCategorien *)value;
- (void)addCategorie:(NSSet *)values;
- (void)removeCategorie:(NSSet *)values;
@end
/*
* News Transformer NSArray -> NSData and reverse
* Model: News should have Attribut type of Transformable and have name NewsTrasformer
*/
@interface NewsTransformer : NSValueTransformer
@end
News.m
#import "News.h"
#import "NewsCategorien.h"
@implementation News
@dynamic categories;
@dynamic content;
@dynamic date;
@dynamic dateTs;
@dynamic detailsUrl;
@dynamic isNews;
@dynamic newsId;
@dynamic primaryCat;
@dynamic title;
@dynamic categorie;
//tell the archiver how to transform the serialized representation into a new object -> deserialize Objects!
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.categories = [decoder decodeObjectForKey:@"categories"];
self.content = [decoder decodeObjectForKey:@"content"];
self.date = [decoder decodeObjectForKey:@"date"];
self.dateTs = [decoder decodeObjectForKey:@"dateTs"];
self.detailsUrl = [decoder decodeObjectForKey:@"detailsUrl"];
self.isNews = [decoder decodeObjectForKey:@"isNews"];
self.newsId = [decoder decodeObjectForKey:@"newsId"];
self.primaryCat = [decoder decodeObjectForKey:@"primaryCat"];
self.title = [decoder decodeObjectForKey:@"title"];
self.categorie = [decoder decodeObjectForKey:@"categorie"];
}
NSLog(@"<<<< ---- Deserialize Object News (Init With Code) --->");
return self;
}
//tell the archiver how to serialize your object into bytes -> serialize Objects!
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.categories forKey:@"categories"];
[encoder encodeObject:self.content forKey:@"content"];
[encoder encodeObject:self.date forKey:@"date"];
[encoder encodeObject:self.dateTs forKey:@"dateTs"];
[encoder encodeObject:self.detailsUrl forKey:@"detailsUrl"];
[encoder encodeObject:self.isNews forKey:@"isNews"];
[encoder encodeObject:self.newsId forKey:@"newsId"];
[encoder encodeObject:self.primaryCat forKey:@"primaryCat"];
[encoder encodeObject:self.title forKey:@"title"];
[encoder encodeObject:self.categorie forKey:@"categorie"];
NSLog(@"<<<< ---- Serialize Object News (encode With Coder) --->");
}
@end
//
@implementation NewsTransformer
//Return the Class for Forwarding Transformation
+ (Class)transformedValueClass
{
return [NSArray class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
// converts the NSArray into NSData using NSKeyedArchiver
- (id)transformedValue:(id)value
{
NSLog(@"Transformer: NSArray -> NSData");
return [NSKeyedArchiver archivedDataWithRootObject:value];
}
// by default raises an exception if +allowsReverseTransformation returns NO and otherwise invokes transformedValue:
//converts NSData to an NSArray using NSKeyedUnarchiver
- (id)reverseTransformedValue:(id)value
{
NSLog(@"Transformer: NSData -> NSArray");
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
}
@end
NewsCategorien.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class News;
@interface NewsCategorien : NSManagedObject <NSCoding>
@property (nonatomic, retain) NSNumber * catId;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) News *news;
//for serializing of objects have to be implement...
- (void)encodeWithCoder:(NSCoder *)aCoder;
//for serializing of objects have to be implement...
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
NewsCategorien.m
#import "NewsCategorien.h"
#import "News.h"
@implementation NewsCategorien
@dynamic catId;
@dynamic name;
@dynamic news;
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.catId = [decoder decodeObjectForKey:@"catId"];
self.name = [decoder decodeObjectForKey:@"name"];
self.news = [decoder decodeObjectForKey:@"news"];
}
NSLog(@"<<<< ---- Deserialize Object Categorie ---> : %@",self.description);
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.catId forKey:@"catId"];
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeObject:self.news forKey:@"news"];
NSLog(@"<<<< ---- Serialize Object Categorie ---> %@",self.description);
}
@end
模型 新闻 属性:categorien类型:可转换名称:NewsTransformer
Relationchip one-to-more 分类Des。 NewsCategorien反向新闻
Categorien ATT。 catId String ATT。名字Interger16
我的问题: 1.将数据写入上下文 - 好的 2.当我试图从上下文中获取数据时(NSData-&gt; NSArray)我得到以下错误:
错误
CoreData: error: Failed to call designated initializer on NSManagedObject class 'NewsCategorien'
2013-11-20 16:03:19.204 securityNews[19458:c07] -[NewsCategorien setCatId:]: unrecognized selector sent to instance 0x8173740
2013-11-20 16:03:19.205 securityNews[19458:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NewsCategorien setCatId:]: unrecognized selector sent to instance 0x8173740'
知道我做错了什么?
答案 0 :(得分:0)
第一个错误几乎肯定是由于您initWithCoder:
的实施,特别是这一行:
if (self = [super init]) {
您无法使用init
创建托管对象。您必须使用指定的初始化程序initWithEntity:insertIntoManagedObjectContext:
。或者您可以使用NSEntityDescription
的方法insertNewObjectForEntityForName:inManagedObjectContext:
。但是使用init
是正确的,这样做会导致Failed to call designated initializer
错误。
这意味着您的initWithCoder
需要能够找到托管对象上下文。如何执行此操作取决于您的应用程序的结构以及创建上下文的位置。如果你的app委托有一个上下文对象,那就是你想要使用的对象,你可以从那里查找它。如果是其他一些背景,你必须从其他地方获得它。你有几个initWithCoder
版本,他们都有这个问题。
第二个错误是第一个错误的副作用。在initWithCoder
中执行此操作:
if (self = [super init]) {
self.catId = [decoder decodeObjectForKey:@"catId"];
....
但是由于[super init]
不起作用,你会找回一个不知道catId
是什么的虚假对象。然后你尝试设置catId
并且它失败了。修复第一个错误,第二个错误将消失。