0

我对 iOS 比较陌生(如果我不清楚或者问题已在其他地方得到解决,我会事先道歉)并且我已经阅读了很多教程来学习基础知识。尽管如此,我在使用核心数据执行以下操作时遇到了问题:

  • 我了解如何使用核心数据从数据库中获取数据、对其进行排序和显示,但现在我不知道如何以编程方式处理需要计算和显示的属性(它是我的数据库中表中的临时属性)在嵌入导航控制器的 tableview 控制器内的静态 tableview 单元格中。

举例说明:我有一个包含两个变量( InputValue (integer) 和 inputDate (NSDate) )的表,我想计算每年或每天输入的每个每日值的平均值/最小值/最大值。然后,这些值将在 tableview 静态单元格中显示和更新(每个单元格中的计算值。)

编辑:我在这里从 tableview 控制器添加了一些代码:

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

    //Configure the cell to show the user value as well as showing the date of input

    PVMesswert *wert = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   [dateFormatter setDateFormat:@"dd.MM.yyyy"];
           cell.textLabel.text= [[NSString alloc] initWithFormat:@"%@ kWh", wert.inputValue];
    cell.detailTextLabel.text = [dateFormatter stringFromDate:wert.inputDate];

     }

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    //should I have a different cell identifier for each row where I want to display a result of the calculations?
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell.
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (NSFetchedResultsController *)fetchedResultsController
{


     if (_fetchedResultsController != nil) {
            return _fetchedResultsController;
        }

        // Create and configure a fetch request with the PVMesswert entity.


        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"PVMessWert" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];

        // Create the sort descriptors array.

        NSSortDescriptor *datumsort = [[NSSortDescriptor alloc] initWithKey:@"inputDate" ascending:NO];

        NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"InputValue" ascending:YES];

        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:datumsort, /*authorDescriptor,*/ nil];
        [fetchRequest setSortDescriptors:sortDescriptors];

        // Create and initialize the fetch results controller.


        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"dateToString" cacheName:@"Root"];

        _fetchedResultsController.delegate = self;

        // Memory management.

        return _fetchedResultsController;
    }    

因此,在我拥有的另一个表格视图中,我想显示如下内容:每年的平均/最大/最小输入值(基于属性输入日期 NSDat。)。我应该使用 NSExpression 吗?在这种情况下,如何使用?

4

2 回答 2

1

您应该使用聚合函数进行此类计算。

您可以在一个相对较快的获取请求中检索所有最大/最小/平均信息。

聚合函数的代码应如下所示:

//Function expression generator
- (NSExpressionDescription*) aggregateFunction:(NSString*)function
                                    forKeyPath:(NSString*)keyPath
                                          name:(NSString*)name
                                    resultType:(NSAttributeType)resultType
{
    NSExpression* keyPathExpression = [NSExpression expressionForKeyPath:keyPath];
    NSExpression* funcExpression = [NSExpression expressionForFunction:function arguments:@[keyPathExpression]];
    NSExpressionDescription* expressionDescription  = [NSExpressionDescription new];
    [expressionDescription setName:name];
    [expressionDescription setExpression:funcExpression];
    [expressionDescription setExpressionResultType:resultType];
    return expressionDescription;
}

您的 fetch 请求应如下所示:

//someValue is an Integer64 property
//someDate is a Date property
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:@"Product"];
NSExpressionDescription* minValueField = [self aggregateFunction:@"min:"
                                                      forKeyPath:@"someValue"
                                                            name:@"minValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* avgValueField = [self aggregateFunction:@"average:"
                                                      forKeyPath:@"someValue"
                                                            name:@"avgValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* maxValueField = [self aggregateFunction:@"max:"
                                                      forKeyPath:@"someValue"
                                                            name:@"maxValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* minDateField = [self aggregateFunction:@"min:"
                                                     forKeyPath:@"someDate"
                                                           name:@"minVDate"
                                                     resultType:NSDateAttributeType];
NSExpressionDescription* avgDateField = [self aggregateFunction:@"average:"
                                                      forKeyPath:@"someDate"
                                                            name:@"avgDate"
                                                      resultType:NSDateAttributeType];
NSExpressionDescription* maxDateField = [self aggregateFunction:@"max:"
                                                     forKeyPath:@"someDate"
                                                           name:@"maxDate"
                                                     resultType:NSDateAttributeType];

[r setResultType:NSDictionaryResultType];
[r setPropertiesToFetch:@[minValueField,avgValueField,maxValueField,minDateField,avgDateField,maxDateField]];

NSArray* results = [context executeFetchRequest:r error:NULL];

注意:
* 这将检索单个字典对象中的信息,其键与name您为其创建表达式的参数匹配。
* 您不能使用 aNSFetchedResultsController来“实时”跟踪结果集中的变化,如果您需要在数据库更改时准确计算,则需要刷新结果。
* 要按日和年分组,您需要将日期字段中的日和年提取到单独的字段中(例如dayyear),然后在获取请求中按这些字段进行分组:

[r setPropertiesToGroupBy:@[@"year"]];//to group by year alone

并将 添加year到要获取的属性中。

编辑:如果您对特定年份(或一年中的某一天)感兴趣,则必须将年份和日期与日期分开(正如我之前提到的)。
然后只需设置一个谓词以按您需要的年份进行过滤:

[r setPredicate:[NSPredicate predicateWithFormat:@"year = %d",someYear]];
于 2013-07-12T03:52:05.587 回答
0

有两种主要方法:

一世。在cellForRowAtIndexPath使用NSFetchedResultsController

- (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell =
        [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // get your managed object
    NSManagedObject *managedObject = [_fetchedResultsController objectAtIndexPath:indexPath];

    // do any computations
    float value1 = [[managedObject valueForKey:@"value1"] floatValue];
    float value2 = [[managedObject valueForKey:@"value2"] floatValue];
    float average = (value1+value2)/2;

    // display average in cell
    cell.textLabel.text = [NSString stringWithFormat:@"Average: %f", average];

    return cell;
}

ii. 另一种方法是使用核心数据框架,例如Sensible TableView。除了自动管理在自定义单元格中显示此类计算之外,这些框架还会自动获取您的数据并显示它们。在使用 Core Data 时为我节省了大量时间。

于 2013-07-10T18:05:02.317 回答