【发布时间】:2014-10-10 14:29:21
【问题描述】:
我有 2 个实体:项目和任务。一个项目可以有很多任务。一对多的关系。
我有一个表格视图控制器,它列出了选定项目的所有任务。还有另一个视图控制器,用于向给定项目添加新任务。问题是添加新任务时,插入不止一次,有时两次有时三次。
我意识到: 第一次添加任务,添加1个任务,第二次添加任务,添加2个任务,第3个任务,添加3个任务等等。
我不知道问题到底出在哪里。
请有人帮忙。
AddTaskViewController 有一个来自 TasksTableViewController 的模态序列
TasksTableViewController.h
#import <UIKit/UIKit.h>
#import "Project.h"
#import "Task.h"
@interface MATasksTableViewController : UITableViewController
@property (strong, nonatomic) NSIndexPath *passedPath;
@property (strong, nonatomic) Project *project;
@property (strong, nonatomic) NSString *taskTitleString;
@property (strong, nonatomic) NSArray *tasksArray;
@end
TasksTableViewController.m
#import "MATasksTableViewController.h"
#import "Project.h"
#import "Task.h"
#import "MACoreDataStack.h"
#import "MAAddTaskViewController.h"
@interface MATasksTableViewController () <NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@end
@implementation MATasksTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.fetchedResultsController performFetch:nil];
_project = [self.fetchedResultsController objectAtIndexPath:_passedPath];
_tasksArray = [_project.task allObjects];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//return [_tasksArray count];
return [_tasksArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
// Configure the cell...
Task *t = [_tasksArray objectAtIndex:indexPath.row];
cell.textLabel.text = t.title;
return cell;
}
-(NSFetchRequest *)projectListFetchRequest {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Project"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"dueDate" ascending:YES]];
return fetchRequest;
}
-(NSFetchedResultsController *) fetchedResultsController {
if(_fetchedResultsController != nil) {
return _fetchedResultsController;
}
MACoreDataStack *coreDataStack = [MACoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self projectListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
MACoreDataStack *coreDataStack = [MACoreDataStack defaultStack];
Task *t = [_tasksArray objectAtIndex:indexPath.row];
[_project removeTaskObject:t];
[coreDataStack saveContext];
[self performFetchAgain];
} 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
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([[segue identifier] isEqualToString:@"AddTaskSegue"]) {
UINavigationController *navController = (UINavigationController*)[segue destinationViewController];
MAAddTaskViewController *destinationVC = [navController topViewController];
destinationVC.project = self.project;
destinationVC.firstViewController = self;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didPressDoneAndDismissController)
name:@"doneWasPressedInSecondView"
object:nil];
}
}
-(void)didPressDoneAndDismissController {
MACoreDataStack *coreDataStack = [MACoreDataStack defaultStack];
Task *task = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:coreDataStack.managedObjectContext];
task.title = self.taskTitleString;
[self.project addTaskObject:task];
[coreDataStack saveContext];
[self performFetchAgain];
}
-(void)performFetchAgain {
[self.fetchedResultsController performFetch:nil];
_project = [self.fetchedResultsController objectAtIndexPath:_passedPath];
_tasksArray = [_project.task allObjects];
[self.tableView reloadData];
}
@end
AddTaskViewController.h
#import <UIKit/UIKit.h>
#import "Project.h"
#import "MATasksTableViewController.h"
@interface MAAddTaskViewController : UIViewController {
Project *project;
MATasksTableViewController *firstViewController;
}
@property(nonatomic,assign)id delegate;
@property (strong, nonatomic) MATasksTableViewController *firstViewController;
@property (strong, nonatomic) IBOutlet UITextField *textField;
@property (strong, nonatomic) Project *project;
@property (nonatomic, strong) NSMutableSet *tasks;
@end
AddTaskViewController.m
#import "MAAddTaskViewController.h"
#import "Project.h"
#import "Task.h"
#import "MACoreDataStack.h"
@interface MAAddTaskViewController ()
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@end
@implementation MAAddTaskViewController
@synthesize project;
@synthesize tasks;
@synthesize firstViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)createNewTask {
NSString* taskTitle = self.textField.text;
self.firstViewController.taskTitleString = taskTitle;
}
-(void)dismissSelf {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)doneWasPressed:(id)sender {
[self createNewTask];
[[NSNotificationCenter defaultCenter] postNotificationName:@"doneWasPressedInSecondView"
object:nil
userInfo:nil];
[self dismissSelf];
}
- (IBAction)cancelWasPressed:(id)sender {
[self dismissSelf];
}
@end
【问题讨论】:
-
欢迎来到 SOF。你不应该转储整个类的代码。这里的习惯是您只需发布您认为相关的代码并对其进行评论。
标签: ios objective-c core-data xcode5