为啥 Core Data 获取请求从自定义 UITableViewCell 返回空?

Posted

技术标签:

【中文标题】为啥 Core Data 获取请求从自定义 UITableViewCell 返回空?【英文标题】:Why does Core Data fetch request return empty from custom UITableViewCell?为什么 Core Data 获取请求从自定义 UITableViewCell 返回空? 【发布时间】:2015-04-27 21:05:35 【问题描述】:

我在 ViewController.m 中有一个名为 getData 的方法,它在 viewDidLoad 内部调用:

-(void)getData 
    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"WorkoutHasExercise" inManagedObjectContext:context];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDesc];
    request.resultType = NSDictionaryResultType;
    request.propertiesToFetch = [NSArray arrayWithObjects:@"exerciseName", @"reps", @"sets", nil];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(workoutName = %@)", _workoutName];
    [request setPredicate:pred];

    NSManagedObject *matches = nil;

    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];

    if ([objects count] == 0) 

     else 
        [_exercises removeAllObjects];
        for (int x = 0; x < [objects count]; x++) 
            matches = objects[x];
            [_exercises addObject:[matches valueForKey:@"exerciseName"]];
            [_totalSets addObject:[matches valueForKey:@"sets"]];
            [_totalReps addObject:[matches valueForKey:@"reps"]];
            [_currentSets addObject:[NSNumber numberWithInteger:0]];
        
    
    [_exercisesTableView reloadData];


我还有一个自定义 UITableViewCell,其中包含在 cellForRowAtIndexPath 中启动的两个按钮:

ActiveWorkoutCell *cell = (ActiveWorkoutCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ActiveWorkoutCell" owner:self options:nil];
cell = [nib objectAtIndex:0];

cell.increaseButton.tag = indexPath.row;
cell.decreaseButton.tag = indexPath.row;

在 ActiveWorkoutCell.m 中,按钮有 2 个 IBAction:

- (IBAction)decreaseSets:(id)sender 
    ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
    [vc decreaseSets:[sender tag]];


- (IBAction)increaseSets:(id)sender 
    ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
    [vc increaseSets:[sender tag]];

IBActions 在 ViewController.m 中调用这 2 个方法

-(void)increaseSets:(NSInteger)row 
    [self getData];
    //There will be code here to increase the value of currentSets[row]


-(void)decreaseSets:(NSInteger)row 
    [self getData]
    //Code to decrease value...

问题:

当从 viewDidLoad 调用 getData 时,它工作正常。 从 ActiveWorkoutCell.m 中的 IBAction 返回 ViewController.m 时会出现问题。 当我在 increaseSets 中调用 [self getData] 时,获取请求返回一个空数组。这让我感到困惑 - 代码在第一次调用时可以正常工作,但在自定义单元格操作被触发后第二次调用时根本不行。

如果有帮助,这是我的 viewDidLoad:

- (void)viewDidLoad 
    [super viewDidLoad];
    _exercises = [NSMutableArray array];
    _totalSets = [NSMutableArray array];
    _currentSets = [NSMutableArray array];
    _totalReps = [NSMutableArray array];

    _titleLabel.text = _workoutName;
    _exercisesTableView.allowsSelection = NO;
    [self getData];

_workoutName 在前一个视图控制器的 prepareForSegue 中被赋予了一个值。

【问题讨论】:

您的NSMutableArray 属性是否正在实例化?如果是这样,当您逐步执行代码时,它们的值是什么? 它们在第一次调用 getData 时(从 viewDidLoad)按预期填充,但是一旦按下自定义单元格中的按钮并触发 ActiveWorkoutCell.m 中的 IBAction,它们就会变为 nil。跨度> 您的 IBAction 会创建 ActiveWorkOutViewController 的新副本。这些新副本不会出现,因此 viewDidLoad 不会运行(在这些副本中)。所以可变数组没有被初始化。 @pbasdf 你能解释一下这个问题以及我应该如何解决它吗? 这一行:ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init]; 创建了一个新的 ViewController 实例。您需要访问现有实例。有几种方法 - 我认为最简单的方法是将 delegate 属性添加到自定义单元格,将 delegate 的值设置为 cellForRowAtIndexPath 中的 self,然后使用 self.delegate 代替 vc 在您的IBAction 方法。 【参考方案1】:

我想我找到了问题所在。当调用 IBAction 方法时,您正在实例化“ActivityWorkOutViewController”,它将是一个新实例,然后在这些方法中,您调用 [self getData] 指向没有实例化变量或 viewDidLoad 的新实例,所以你的可变数组没有分配,因此它们是空的。

只需使用类的旧实例来获取数据。

我不确定您是如何引用这些类的。我只是对此感到困惑。但是,您可能会检查分配并调用正确的类来获取数据

【讨论】:

因为我现在编辑了我的帖子以包含,代码在第一次从 viewDidLoad 运行时工作正常,所以这不是问题 感谢您的回答 - 如何使用该类的旧实例? (我对Objective-C中的OOP不太了解) is "ViewController.m" is "ActivityWorkoutController" 你在上面的问题中引用?如果是这样,请在 Cell 类上创建一个委托方法,并使用 ActivityWorkoutController 类上的委托方法在这些委托方法中调用 [self getData] 方法。这样它将使用现有的类。

以上是关于为啥 Core Data 获取请求从自定义 UITableViewCell 返回空?的主要内容,如果未能解决你的问题,请参考以下文章

为啥从自定义单元格调用时 UIkeyboard 不动画?

.Net Core:从自定义异常中间件返回 IActionResult

Core Data:为啥要创建自定义持久存储?

Flex 4 从自定义组件调度自定义事件(为啥 flex 将自定义事件转换为 mouseevent)

为啥我的应用程序在从自定义视图启动 Activity 后关闭?

为啥从自定义 UIView 向 UIButton 添加子视图不显示添加的子视图?