iam*_*isg 1 core-data objective-c ios
好吧,我已经在这个问题上打了一段时间,现在已经过了一个星期,我只是不知道自己哪里出错了.非常感谢您的帮助!!
这是应用程序的想法.我有两个以核心数据为模型的实体.大亨实体与Speech有一对多的关系,因此每个大亨都能够有多个演讲.在Tycoon实体中,这种关系的标题是"TycoonToSpeech",而在言语实体中,与Tycoon的关系标题为"SpeechToTycoon"(这不是一对多的关系).
问题1:我认为我已经在appdelegate.m文件中正确创建了我的关系,但我不确定.以下是我的appdelegate中用于生成内容的代码.我应该用NSMutableSets做更多的事吗???
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *tycoonEntity = [NSEntityDescription entityForName:@"Tycoon" inManagedObjectContext:context];
NSManagedObject *steve = [NSEntityDescription insertNewObjectForEntityForName:[tycoonEntity name] inManagedObjectContext:context];
[steve setValue:@"Steve Jobs" forKey:@"Name"];
int orgId = [steve hash];
[steve setValue:[NSNumber numberWithInt:orgId] forKey:@"Id"];
NSManagedObject *warren = [NSEntityDescription insertNewObjectForEntityForName:[tycoonEntity name] inManagedObjectContext:context];
[warren setValue:@"Warren Buffet" forKey:@"Name"];
int orgId2 = [warren hash];
[warren setValue:[NSNumber numberWithInt:orgId2] forKey:@"Id"];
NSEntityDescription *speechEntity = [NSEntityDescription entityForName:@"Speech" inManagedObjectContext:context];
NSManagedObject *stanford = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[stanford setValue:[NSNumber numberWithInt:[stanford hash]] forKey:@"speechId"];
[stanford setValue:@"Stanford" forKey:@"speechName"];
NSManagedObject *wwdc = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[wwdc setValue:[NSNumber numberWithInt:[wwdc hash]] forKey:@"speechId"];
[wwdc setValue:@"WWDC" forKey:@"speechName"];
NSManagedObject *shareHolder = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[shareHolder setValue:[NSNumber numberWithInt:[shareHolder hash]] forKey:@"speechId"];
[shareHolder setValue:@"Shareholder's Meeting" forKey:@"speechName"];
NSManagedObject *columbia = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[columbia setValue:[NSNumber numberWithInt:[columbia hash]] forKey:@"speechId"];
[columbia setValue:@"Columbia" forKey:@"speechName"];
NSMutableSet *jobsSpeeches = [steve mutableSetValueForKey:@"TycoonToSpeech"];
[jobsSpeeches addObject:stanford];
[jobsSpeeches addObject:wwdc];
NSMutableSet *warrenSpeeches = [warren mutableSetValueForKey:@"TycoonToSpeech"];
[warrenSpeeches addObject:shareHolder];
[warrenSpeeches addObject:columbia];
Run Code Online (Sandbox Code Playgroud)
问题2:主要且非常烦人的问题,我不知道如何在我的根视图控制器中使用didSelectRowAtIndexPath工作,这样当我在表格视图中点击"史蒂夫·乔布斯"时,它只显示他的演讲,当我点击在沃伦自助餐上,它只会提出他的演讲.为了做到这一点,我把头撞在了墙上.目前,当我点击史蒂夫乔布斯或沃伦巴菲特时,它会带我到一个新的桌面视图,显示'史蒂夫乔布斯'和'沃伦巴菲特',所以基本上与原始的表视图完全相同!这是我的didSelectRowAtIndexPath代码.
// Create a new table view of this very same class.
RootViewController *rootViewController = [[RootViewController alloc]
initWithStyle:UITableViewStylePlain];
// Pass the managed object context
rootViewController.context = self.context;
NSPredicate *predicate = nil;
// Get the object the user selected from the array
NSManagedObject *selectedObject = [entityArray objectAtIndex:indexPath.row];
rootViewController.entityName = @"Speeches";
// Create a query predicate to find all child objects of the selected object.
predicate = [NSPredicate predicateWithFormat:@"SpeechToTycoon == %@", selectedObject];
[rootViewController setEntitySearchPredicate:predicate];
//Push the new table view on the stack
[self.navigationController pushViewController:rootViewController animated:YES];
[rootViewController release];
Run Code Online (Sandbox Code Playgroud)
这里新编辑**
好的,这是我的SpeechViewController.m文件中的主要代码.numberOfRowsInSection方法似乎正在工作,但真正的问题是cellForRowAtIndexPath是问题所在.我知道我可能做的事非常愚蠢,但我不知道它是什么.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSArray *speeches = (NSArray *)tycoon.TycoonToSpeech;
// Configure the cell...
cell.textLabel.text = [[speeches objectAtIndex:indexPath.row] retain];
return cell;
Run Code Online (Sandbox Code Playgroud)
}
新的语音视图控制器到语言点视图控制器
我在app委托中添加了这个,以便将对象添加到我的语言点实体.
NSEntityDescription *langPointEntity = [NSEntityDescription entityForName:@"LanguagePoints" inManagedObjectContext:context];
NSManagedObject *pointOne = [NSEntityDescription insertNewObjectForEntityForName:[langPointEntity name] inManagedObjectContext:context];
[pointOne setValue:[NSNumber numberWithInt:[pointOne hash]] forKey:@"LangId"];
[pointOne setValue:@"Drop out" forKey:@"LangPoint"];
[pointOne setValue:stanford forKey:@"LanguagePointsToSpeech"];
Run Code Online (Sandbox Code Playgroud)
然后在我的speechViewController.m文件中创建了一个名为speechInfo的NSArray,然后这是我的didSelectRowAtIndexPath方法.
LangPointsViewController *langPointsView = [[LangPointsViewController alloc] initWithNibName:@"LangPointsViewController" bundle:[NSBundle mainBundle]];
Speech *speech = [speechInfo objectAtIndex:indexPath.row];
langPointsView.speech = speech;
[self.navigationController pushViewController:langPointsView animated:YES];
[langPointsView release];
Run Code Online (Sandbox Code Playgroud)
我认为这是出错的地方,我不认为我正确地得到了这个对象,因为我在LangPointsViewController上的speech.Name上做了一个NSLog,它出现了null,好像我为大亨做了一个NSLog. SpeechViewController中的名称会打印我单击的人名.NSArray是不正确的吗?
首先你的关系名称不好.它们应该以小写字母开头,它们应该简单地描述关系另一方面的内容.你已经知道你在哪里.所以,他们的名字tycoon和speeches分别.其次,由于关系是双向的,您可以更轻松地构建数据,请参阅以下内容:
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *steve = [NSEntityDescription insertNewObjectForEntityForName:@"Tycoon" inManagedObjectContext:context];
[steve setValue:@"Steve Jobs" forKey:@"Name"];
int orgId = [steve hash];
[steve setValue:[NSNumber numberWithInt:orgId] forKey:@"Id"];
NSManagedObject *warren = [NSEntityDescription insertNewObjectForEntityForName:[tycoonEntity name] inManagedObjectContext:context];
[warren setValue:@"Warren Buffet" forKey:@"Name"];
int orgId2 = [warren hash];
[warren setValue:[NSNumber numberWithInt:orgId2] forKey:@"Id"];
NSManagedObject *stanford = [NSEntityDescription insertNewObjectForEntityForName:@"Speech" inManagedObjectContext:context];
[stanford setValue:[NSNumber numberWithInt:[stanford hash]] forKey:@"speechId"];
[stanford setValue:@"Stanford" forKey:@"speechName"];
[stanford setValue:warren forKey:@"tycoon"];
NSManagedObject *wwdc = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[wwdc setValue:[NSNumber numberWithInt:[wwdc hash]] forKey:@"speechId"];
[wwdc setValue:@"WWDC" forKey:@"speechName"];
[wwdc setValue:warren forKey:@"tycoon"];
NSManagedObject *shareHolder = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[shareHolder setValue:[NSNumber numberWithInt:[shareHolder hash]] forKey:@"speechId"];
[shareHolder setValue:@"Shareholder's Meeting" forKey:@"speechName"];
[shareHolder setValue:warren forKey:@"tycoon"];
NSManagedObject *columbia = [NSEntityDescription insertNewObjectForEntityForName:[speechEntity name] inManagedObjectContext:context];
[columbia setValue:[NSNumber numberWithInt:[columbia hash]] forKey:@"speechId"];
[columbia setValue:@"Columbia" forKey:@"speechName"];
[columbia setValue:warren forKey:@"tycoon"];
Run Code Online (Sandbox Code Playgroud)
请注意,我从Speech侧面设置关系.核心数据将处理另一方.
如果不查看整个根视图控制器,很难说你做错了什么.但是,我不会重复使用视图控制器来显示两种不同类型的对象.这是糟糕的形式,导致代码残酷.
相反,我会创建第二个"主"视图控制器,旨在处理语音.然后你可以传入大亨,你的SpeechViewController可以运行从关系派生的数组,或者它可以在内部构建其获取的结果控制器.即使更有价值的是能够自定义其单元格,标题等以适合它正在显示的数据.
首先评论您添加的新代码:
SpeechViewController *speechView = [[SpeechViewController alloc] initWithNibName:@"SpeechViewController" bundle:[NSBundle mainBundle]];
Tycoon *tycoons = (Tycoon *)[fetchedResultsController objectAtIndexPath:indexPath];
speechView.tycoons = tycoons;
[self.navigationController pushViewController:speechView animated:YES];
Run Code Online (Sandbox Code Playgroud)
有ZERO理由赶出去的-[NSFetchedResultsController objectAtIndexPath:].任何返回的方法id都可以分配给任何指针.
转换是编译器的谎言,应该不惜一切代价避免.
现在,把它放在一边,你的代码很好.我会将该物业命名为"大亨"而不是"大亨",因为您正在传递一个大亨实体.
在SpeechViewController侧面,您现在可以访问与该Tycoon实体相关联的演讲,并根据您的选择显示它们.
你看到的问题是什么?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSSet *speechesSet = [[self tycoon] valueForKey:@"TycoonToSpeech"];
// Sort the speeches
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortedSpeeches = [speechesSet sortedArrayUsingDescriptors:[NSArray arrayWithObject:nameSort]];
// Configure the cell...
id speech = [sortedSpeeches objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[speech valueForKey:@"name"]];
return cell;
}
Run Code Online (Sandbox Code Playgroud)
好的,从顶部开始.首先,关系将返回NSSet不是a NSArray.关系的结果是无序的.因此,我们将结果作为a抓取NSSet,然后对它们进行排序.我猜想你的Speech实体有一个名字属性.
一旦我们对它们进行了排序,我们就可以抓住该行的项目.这将返回一个Speech实体.我指定了它,id因为无论如何我们将使用KVC.
最后,我使用KVC name从Speech实体获取属性并将其分配给textLabel单元格.
至于你-tableView: numberOfRowsInSection:,那个更简单:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self tycoon] valueForKey:@"TycoonToSpeech"] count];
}
Run Code Online (Sandbox Code Playgroud)
因为您只有一个部分,所以您只需要返回演讲次数.
我之前提到过你的属性名称需要一些工作.因为Tycoon它只是一个对象而且只是该对象的TycoonToSpeech一个属性,所以应该真正调用该属性,speeches因为它不比对象上的任何其他属性更特殊.属性名称在代码中流动得更好,使代码更容易使用.此外,Objective-C命名约定要求属性aka属性以小写字母开头.
| 归档时间: |
|
| 查看次数: |
3133 次 |
| 最近记录: |