【问题标题】:Do I need more than one persistant store?我需要多个持久性商店吗?
【发布时间】:2010-07-07 12:07:07
【问题描述】:

我正在尝试创建一个由核心数据支持的列表应用程序。第一页允许您创建任意数量的列表并命名它们。通过在第一个视图中点击名称,您将被带到该实际列表,您可以在该列表中创建项目。但是,如果我创建 3 个列表,它们每个都有相同的数据。每个第一个视图单元格是否需要不同的商店?另外,如果我这样做,如何使它创建一个新商店,并添加每个新单元格?感谢您的帮助。!

alt text http://www.tckdeveloper.com/Tutorials/iPhone/Screen%20shot%202010-07-07%20at%208.11.52%20AM.png

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

//This is the second view that holds the list items
RootViewController *secondViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];

secondViewController.managedObjectContext = [self managedObjectContext];

[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];

}

Rootview.m

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[fetchedResultsController sections] count];
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}


// Customize the appearance of table view cells.
- (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];
}

// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

return cell;
}


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

// Configure the cell to show the book's title
Book *book = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = book.title;
}


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// Display the authors' names as section headings.
return nil;
}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {

    // Delete the managed object.
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

    NSError *error;
    if (![context save:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }
}   
}

【问题讨论】:

    标签: iphone core-data save


    【解决方案1】:

    您设计数据模型的依据不是数据的显示方式,而是数据与自身的逻辑关联方式。每个实体都应该对现实世界的对象、事件或条件进行建模,而不考虑这些数据最终将如何显示。

    在这种情况下,您正在对书籍进行建模,并且用户提供了将这些书籍组织到列表中的方式。您需要一个书籍实体来为书籍建模,并需要一个列表实体来为用户组织建模。 (不一定是“列表”,也可以是“收藏”、“货架”等,具体取决于您要建模的内容。)

    大概,每本书可以在不同的列表中,每个列表可能包含很多书。

    Book {
        author:string;
        copyright:sting/date;
        item:(?);
        title:sting;
        list<<-(optional,nullify)-->>list.books
    }
    
    List {
        name:string;
        books<<--(optional,nullify)-->>book.list;
    }
    

    在您的 UI 中,您可以让获取结果控制器 (FRC) 获取所有列表实体,然后在表格视图中显示每个实体的名称。选择表行时,将下一个视图按下下一个视图,然后将其递送列表与该行关联的列表对象的books返回的nsset。

    在下一个表视图中,每一行都由传递集合中每个书籍实体的一个或多个属性填充。选择行时,您推送一个书籍详细信息视图并将与所选行关联的书籍实体传递给它。

    请注意,从数据模型的角度来看,UI 是无关紧要的。您可以在 Web 视图甚至基于文本的命令行中显示数据。所有数据模型关心的是实体的内容以及它们之间的逻辑关系。

    设计您的数据模型以处理数据中的逻辑关系。一旦你这样做了,无论格式如何,UI 的实现都变得非常简单,因为 UI 不负责维护数据模型的完整性,并且数据模型不必担心 UI 的状态。

    【讨论】:

    • 非常感谢。如果我有足够的代表,我会向上箭头。提供的代码,这是实际的数据模型正确吗?这意味着我不必在任何地方添加此代码?我现在也理解了逻辑,但是当我不知道用户将如何命名列表并且我不知道用户将在不同列表中放入多少项目时,我该如何过滤每个列表项。感谢您迄今为止的帮助。
    • 这不是代码。它只是一种表示实体图的文本方式。每个列表对象代表一个单独的列表,并维护自己的自定义相关书籍对象集。您在创建列表时拥有用户名,并让用户将他想要的书籍添加到列表中。当用户选择一个列表时,bam,您在所选列表对象中拥有列表中的所有书籍。
    • 不要混淆实体和托管对象。实体类似于类,即它们定义属性和关系,但本身不保存数据或逻辑。保存数据和逻辑的是托管对象的各个实例。实体图/模型告诉上下文托管对象如何相互关联。即使您只有两个实体,也可以在运行时转换为功能上无限数量的托管对象。因此,您可以拥有大量列表对象,每个对象都包含自己的书籍对象集。
    • 我从来没有处理过 NSSet,所以我为我的无知道歉。我是否为每个不同的列表创建不同的托管对象?比如list "A" managedObject "A" list "B" managedObject "B"?对不起,我还是有点困惑。
    • 是的,完全正确。每个列表都由其自己的对象表示。这可以是通用 NSManagedObject 的一个实例,也可以创建一个名为“list”的专用 NSManagedObject 子类(名称实际上是任意的,只要您告诉模型它是什么。)同样,每本书都作为自己的对象/实例也是如此。 Core Data 为您管理所有这些对象。您只需告诉 Core Data 通过插入和获取它们来创建它们。其他一切(内存、关系、磁盘访问等)都是自动的。
    【解决方案2】:

    不,您绝对不需要为每个添加的单元格单独存储。

    您需要一个符合您要求的数据模型。 列表-----ListEntry。

    第一页显示所有“List”实体,选择一个列表后,显示所有与“List”有关系的“ListEntries”。

    【讨论】:

    • 是的,我刚刚为列表项添加了另一个实体。我的问题是所有列表现在都有相同的项目。这样我创建了一个列表并将其命名为“A”,然后在列表“A”中添加“apple”。然后我创建列表“B”“apple”也在列表“B”中。我该如何解决这个问题?
    • @Tanner - 在 List 和 ListEntry 之间使用一对多或多对多的关系,然后在您深入到列表时过滤您的获取请求以仅显示属于正在显示列表。
    • 所以对于实体ListItems,有一个NSString的属性叫做items。我如何用每个列表过滤这个是我不明白的部分。谢谢
    • 请发布您的数据模型的屏幕截图,这将使帮助更容易。
    • 完整图片可以在tckdeveloper.com/Tutorials/iPhone/…找到我使用核心数据书作为起点。第一组代码 (didSelectRow) 来自允许您创建列表并命名它们的第一个视图。选择一个列表会将您带到根视图,这是我发布的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 2019-07-18
    相关资源
    最近更新 更多