UITableView 更新正确数量的 managedObjects,但不会显示值

Posted

技术标签:

【中文标题】UITableView 更新正确数量的 managedObjects,但不会显示值【英文标题】:UITableView updates for correct number of managedObjects, but won't display values 【发布时间】:2015-04-15 03:51:52 【问题描述】:

我有一个tableViewController,它在顶部显示一个“添加”(静态)单元格,我希望它列出从managedObjectContext 中提取的对象(动态单元格)的属性。我发现this post 有助于使“添加”单元工作,但现在我已将对象保存到managedObjectContext,我发现它不会显示managedObjectContext 中对象的属性。

为了“查看”发生了什么,我将“动态”单元格设为橙色。当我将类别添加到managedObjectContext 时,橙色单元格的数量会正确更新,但我的managedObjectNSString)的属性无法显示在单元格中。

在我的fetchRequest 完成后,我在其中设置了一个断点,以查看数组中是否有LocationCategories(我的NSManagedObject)--有。

CategoryTVC.h

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) LocationCategory *category;

CategoryTVC.m

    #define NUMBER_OF_STATIC_CELLS 1 // this can be updated

    // Sets up an array to dump LocationCategories into
    @property (nonatomic, strong) NSArray *locationCategories;

    // cell identifier strings
    static NSString *DynamicIdentifier = @"DynamicIdentifier";
    static NSString *StaticIdentifier = @"StaticIdentifier";

 - (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];

    self.title = @"Select a Category";

    // Core Data
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
    self.managedObjectContext = [appDelegate managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"LocationCategory" inManagedObjectContext:self.managedObjectContext]];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"categoryName" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1];
    [fetchRequest setSortDescriptors:sortDescriptors];
    NSArray *categories = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
    self.locationCategories = categories; // probably duplicate to line above, but modeling Apple's sample code


- (void)viewDidLoad 
    [super viewDidLoad];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:DynamicIdentifier];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:StaticIdentifier];



- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
    if (section == 0) 
        return @"";
     else if (section == 1) 
        return @"Categories";
     else 
        // This is just to shut up the compiler
        return nil;
    


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 2;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    if (section == 0) 
        return 1;
     else 
        return self.locationCategories.count;
    


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    if (indexPath.section == 0) 
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:StaticIdentifier];

        if (cell == nil) 
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StaticIdentifier];
        

        cell.textLabel.text = @"Create new category";
        return cell;
     else if (indexPath.section == 1) 
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DynamicIdentifier];

        if (cell == nil) 
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:DynamicIdentifier];
        

        NSManagedObject *locationCategory = [self.locationCategories objectAtIndex:indexPath.row];
        cell.textLabel.text = [locationCategory valueForKey:@"categoryName"];
        cell.backgroundColor = [UIColor orangeColor]; // TODO: Gives cell a color to see how many self.locationCategories there are
        return cell;
    
    return nil;

为了完整起见,我在下面添加了我的 LocationCategory 类:

**LocationCategory.h**
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class PointOfInterest;

@interface LocationCategory : NSManagedObject

@property (nonatomic, retain) id categoryColor;
@property (nonatomic, retain) NSString * categoryName;
@property (nonatomic, retain) NSSet *pointOfInterest;
@end

**LocationCategory.m**

#import "LocationCategory.h"
#import "PointOfInterest.h"

@implementation LocationCategory

@dynamic categoryColor;
@dynamic categoryName;
@dynamic pointOfInterest;

@end

【问题讨论】:

【参考方案1】:

您需要在获取请求后在表视图上调用 reloadData(因此 viewWillAppear 中的最后一行)。

此外,当您为单元格注册类时,不需要 if (cell==nil) 子句,因为您的单元格永远不会为 nil。

【讨论】:

【参考方案2】:

虽然我很想删除这个问题,但我会保留它,以防其他人犯我犯的同样(愚蠢)错误。

@rdelmar 发现一个更新问题,通过在CategoryTVC.m 中的viewWillAppear 中添加以下行来解决这个问题:

[self.tableView reloadData];

我有另一个名为 AddCategoryViewController 的 ViewController,上面有以下属性。

@property (strong, nonatomic) IBOutlet UITextField *categoryNameTextField;
@property (strong, nonatomic) NSString *categoryName;

当我保存新的 LocationCategory 时,我的保存是这样的:

- (IBAction)saveCategory:(id)sender 
    NSLog(@"Save Button Clicked");
    NSError *error;
    error = nil;
    LocationCategory *newCategory = [NSEntityDescription insertNewObjectForEntityForName:@"LocationCategory" inManagedObjectContext:self.managedObjectContext];
    newCategory.categoryName = self.categoryName; // THIS IS WRONG!!!!
    newCategory.categoryColor = self.categoryColor;
    [self.managedObjectContext save:&error];
    [[self navigationController] popViewControllerAnimated:YES];
    NSLog(@"AddCategoryViewController popped off");

上面不正确的行应该是:

newCategory.categoryName = self.categoryNameTextField.text;

我的错误的最终结果是它在我的 managedObjectContext 中倾倒了乱七八糟的东西,并使它看起来好像是为了 self.locationCategories.count 的目的而存在的。

【讨论】:

以上是关于UITableView 更新正确数量的 managedObjects,但不会显示值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableView 内的 UICollectionView 内获取数组数组并返回正确数量的项目?

从 UITableView 插入和删除行时如何正确更新数据源?

UITableView 在更新 NSFetchedResultsController 时保持滚动在正确的位置

如何在滚动时更新 UITableView 数据

更新 UITableView 使用的数据模型数组的正确方法 [关闭]

UITableView / UISearchBar 返回不正确的结果