2013-05-12 2 views
0

Я новичок в этом coredata. Чтобы быть знакомым с отношениями, я создал два объекта CategoryList (состоит из атрибутов «категории») и ExpenseList (состоит из атрибута «amountpent»), который имеет множество отношений. Отношение «CategoryList» к «ExpenseList» - «expenselist». 1-TableView показывает общий расход в каждой категории, какперезагрузка tableview в соответствии с уведомлением после удаления объекта в coredata показывает странный результат

food    -150 
transportation -100 
mobile   -100 
shopping   -500  

и второго Tableview показан отдельные расходы, как

food    -100 
food    -50 
transportation -100 
mobile   -50 
mobile   -50 
shopping   -200 
shopping   -100 
shopping   -200 

Я написал коды для удаления отдельных расходов строки из моего второго Tableview с помощью объект id с момента его потокобезопасности. Когда я удалить запись пищи из моего второго табличном сказать

food    -50 

и когда я вернуться обратно к 1-ой Tableview он должен обновить пищу и показать

food    -100 

Я зарегистрировал первый TableView с уведомлением по умолчанию центра и первое представление таблицы отправляет уведомление (проверено nslog) всякий раз, когда объект удаляется. Когда первое представление таблицы получает уведомление, оно перезагружает данные в представлении таблицы. Но при перезагрузке tableview отображает нежелательное значение для категории, объект которой удален из следующего представления таблицы. Оба вида таблиц связаны контроллером навигации.

Вот мой m.file для 1-го стола.

#import "displayTable.h" 
#import "CategoryList.h" 
#import "ExpenseList.h" 
#import "IncomeList.h" 
#import "coreAppDelegate.h" 
@interface displayTable() 

@end 

@implementation displayTable 
- (NSManagedObjectContext *)managedObjectContext 
{ 
    NSManagedObjectContext *context = nil; 
    id delegate = [[UIApplication sharedApplication] delegate]; 
    if ([delegate performSelector:@selector(managedObjectContext)]) { 
     context = [delegate managedObjectContext]; 
    } 
    return context; 
} 
- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
    // Custom initialization 
    } 
    return self; 
} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    todaysL = [[todayslist alloc]init]; 
    self.expenseArray = [[NSMutableArray alloc] 
         initWithObjects:@"0.00", 
             @"0.00", 
             @"0.00", 
             @"0.00", 
             @"0.00", 
             @"0.00", 
             nil]; 
    self.categoryArray = [[NSMutableArray alloc] 
        initWithObjects:@"food", 
            @"transportation", 
            @"fuel", 
            @"mobile", 
            @"shopping", 
            @"others", 
            nil]; 
    [self populateExpenses]; 
    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; 
    [[NSNotificationCenter defaultCenter]   
     addObserverForName:NSManagedObjectContextObjectsDidChangeNotification 
        object:nil 
        queue:[NSOperationQueue mainQueue] 
       usingBlock:^(NSNotification *notification) 
       { 
        NSLog(@"Notification received!"); 
        [self populateExpenses]; 
        // [self viewDidLoad]; 
        [self.tableView reloadData]; 
       }]; 
// Uncomment the following line to preserve selection between presentations. 
// self.clearsSelectionOnViewWillAppear = NO; 
// Uncomment the following line to display an Edit button in the navigation bar for this view controller. 

// self.navigationItem.rightBarButtonItem = self.editButtonItem; 

} 
- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

#pragma mark-Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    //#warning Potentially incomplete method implementation. 
    // Return the number of sections. 
    return 1; 

} 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    //#warning Incomplete method implementation. 
    // Return the number of rows in the section. 
    return [self.categoryArray count]; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 
    // Configure the cell... 

    if(cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
            reuseIdentifier:CellIdentifier]; 
    } 
    cell.textLabel.text = [_categoryArray objectAtIndex:indexPath.row]; 
    cell.detailTextLabel.text = [_expenseArray objectAtIndex:indexPath.row]; 
    return cell; 
} 

это моя функция для извлечения данных

-(void)populateExpenses 
{ 

    NSManagedObjectContext *managedObjectContexts = [self managedObjectContext]; 
    NSEntityDescription *categorylistEntity = [NSEntityDescription entityForName:@"CategoryList" inManagedObjectContext:managedObjectContext]; 
    NSFetchRequest *request = [[NSFetchRequest alloc]init]; 
    [request setEntity:categorylistEntity]; 
    NSError *error =nil; 
    NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:&error]; 
    if(fetchedObjects == nil) 
    { 
     NSLog(@"your fetching cause error"); 
    } 
    else 
    { 
     for(CategoryList *categoryL in fetchedObjects) 
     { 
      if([categoryL.categories isEqualToString: @"food"]) 
      { 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        food = food + expenseL.amountSpent; 
        //NSLog(@"display food %f",food);      
       } 
       NSString *foodString = [NSString stringWithFormat:@"%.2f",food]; 
       [self.expenseArray replaceObjectAtIndex:0 withObject:foodString]; 
       //NSLog(@"foooood%f",food); 
      } 
      else if ([categoryL.categories isEqualToString: @"transportation"]) 
      { 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        transportation = transportation + expenseL.amountSpent; 
       } 
       NSString *transportationString = [NSString stringWithFormat:@"%.2f",transportation]; 
       [self.expenseArray replaceObjectAtIndex:1 withObject:transportationString]; 
      } 
      else if ([categoryL.categories isEqualToString: @"fuel"]) 
      { 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        fuel = fuel + expenseL.amountSpent; 
       } 
       NSString *fuelString = [NSString stringWithFormat:@"%.2f",fuel]; 
       [self.expenseArray replaceObjectAtIndex:2 withObject:fuelString]; 
      } 
      else if([categoryL.categories isEqualToString: @"mobile"]) 
      { 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        mobile = mobile + expenseL.amountSpent; 
       } 
       NSString *mobileString = [NSString stringWithFormat:@"%.2f",mobile]; 
       [self.expenseArray replaceObjectAtIndex:3 withObject:mobileString]; 
      } 
      else if([categoryL.categories isEqualToString: @"shopping"]) 
      { 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        shopping = shopping + expenseL.amountSpent; 
       } 
       NSString *shoppingString = [NSString stringWithFormat:@"%.2f",shopping]; 
       [self.expenseArray replaceObjectAtIndex:4 withObject:shoppingString]; 
      } 
      else if ([categoryL.categories isEqualToString:@"others"]) 
       for(ExpenseList *expenseL in categoryL.expenselist) 
       { 
        others = others + expenseL.amountSpent; 
       } 
       NSString *othersString = [NSString stringWithFormat:@"%.2f",others]; 
       [self.expenseArray replaceObjectAtIndex:5 withObject:othersString]; 
      NSLog(@"%@",othersString); 
      } 
     //NSLog(@"count %d", self.expenseArray.count); 
    } 
} 
/* 

// Override to support conditional editing of the table view. 

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// Return NO if you do not want the specified item to be editable. 
return YES; 
} 
*/ 

/* 
// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
if (editingStyle == UITableViewCellEditingStyleDelete) { 
    // Delete the row from the data source 
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
} 
else if (editingStyle == UITableViewCellEditingStyleInsert) { 
    // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 
} 
} 
*/ 

/* 
// Override to support rearranging the table view. 
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
{ 
} 

*/ 

/* 

// Override to support conditional rearranging of the table view. 

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// Return NO if you do not want the item to be re-orderable. 
    return YES; 
} 

*/ 

#pragma mark - Table view delegate 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// Navigation logic may go here. Create and push another view controller. 
/* 
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; 

// ... 

// Pass the selected object to the new view controller. 

[self.navigationController pushViewController:detailViewController animated:YES]; 

*/ 
} 
@end 

но когда я выйти и перезапустить мое приложение все обновляется, как это должно быть, но не обновляется сразу после удаления. Я не мог понять, почему. Также я не знаю, является ли это правильным способом делать вещи с coredata. Если бы кто-нибудь мог мне помочь, спасибо заранее

ответ

0

Да, вам не хватает некоторых основных концепций основных данных, а это значит, что вы делаете гораздо больше работы, чем вам нужно.

У вас есть имена категорий верхнего уровня в базе данных, но вы не знаете, в каком порядке их собираетесь вводить, поэтому вы создаете отдельный массив и делаете кучу сложных вещей, чтобы получить значения из базы данных в том же порядке. Гораздо лучше просто добавить поле «displayOrder» в базу данных и добавить порядок по полю в выборку.

Избавьтесь от своего свойства categoryArray полностью и в своей функции populateExpenses, просто выполните выборку (с предложением сортировки). Сохраните fetchedObjects в свойстве array.

Вам нужно сделать выборку, чтобы получить объекты верхнего уровня в первую очередь, но как только вы их получите, редко вам нужно делать больше заданий.

В вашем cellForRowAtIndexPath:

CategoryList * категория = [_fetchedObjects objecatAtIndex: indexPath.row]; cell.textLabel.text = category.categories; cell.detailTextLabel.text = [[category valueForKeyPath: @ "expenselist. @ sum.amountSpent"] description];

Вам не нужно предварительно выбирать это, вы можете сделать это во время отображения данных.

Обновление объектов для обеспечения изменения принимаются уведомления: -

for (NSManagedObject* object in self.categoryArray) { 
    [self.managedObjectContext refreshObject: object mergeChanges:YES]; 
} 

Что это делает, большую часть времени, это сказать объект, который он должен повторно обновления это значение в следующий раз они просил.

Надеюсь, это поможет.

+0

Я пробовал этот код, и когда я запускаю, мое приложение аварийно показывает сообщение: этот класс не является ключевым значением, совместимым с кодировкой для ключа expenselist. ' –

+0

ОК, я вижу, что я был слишком общим, я отредактирую ответ –

+0

Спасибо большое, я сообщу вам, попробовав это –

0

Я решил его решить, просто очистив значения переменных float после их хранения в массиве. так как раньше я не очищал переменные float, а при перезагрузке табличного представления предыдущие значения в float-переменных также снова добавляются, тем самым давая нежелательные значения. так что в методе viewWillAppear я написал reload table view и очистил содержимое переменных float, и он сработал.

Смежные вопросы