我需要帮助重构我的方法更好的逻辑

时间:2011-05-28 18:08:16

标签: iphone objective-c core-data

更新

我对这个方法有这个问题: 默认情况下,视图会将当天设置为今天,并创建会话,将今天的日期作为timeStamp,除非用户手动更改日期。

如果我在今天的日期添加运动,一切都很好。

如果我选择上一个日期并为其添加练习,看起来很好,但似乎练习不仅会添加到此前一个日期,还会添加到今天。

因此,无论我选择的是什么日期,都会将该实体实体添加到该会话和今天的会话中。

因此,当我在tableview中查看今天的会话时,它会完成所有练习,因为所有内容都会随着手动选择的日期一起添加到今天。

我该如何解决这个问题?

原始

我有一个detailViewController,它负责处理核心数据对象Session,Exercise,&设置。

视图的目的是让用户输入有关健身锻炼的详细信息。默认情况下,日期设置为今天,但用户可以将其更改为以前的日期。在createSession中,当用户按下该日期的完成按钮并且日期尚不存在时,将创建一个具有该日期时间戳的新Session对象。如果它已经存在,则使用该timeStamp日期获取该对象。

问题是,即使用户以后没有输入必要的数据,也会创建一个新的Session对象。创建会话后,将提示用户输入用于练习的权重和代表。如果用户没有输入此信息(对象集),则会有一个没有用途的Session对象,因为它们没有练习并且设置了与之相关的对象。

但是我在检查weight / rep之前创建Session对象的原因是因为如果获取了Session,我想在视图中显示它的属性数据,因此我需要在添加sets / reps之前使用它。 / p>

我目前的代码是:

    -(void)createSession
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat: @"(timeStamp >= %@ && timeStamp <= %@)", targetDateBegins, targetDateEnds]];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Session" inManagedObjectContext:managedObjectContext]];

    NSError *error = nil;
    NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    NSLog(@"Fetch error: %@", error);

    if ([results count])
    {
        session = (Session *)[results objectAtIndex:0];
    }
    else
    {
        session = (Session *)[NSEntityDescription insertNewObjectForEntityForName:@"Session" inManagedObjectContext:managedObjectContext];
        session.timeStamp = self.picker.date;
    }

    NSSet *filteredExercisesFromSession=[session.exercises filteredSetUsingPredicate:[NSPredicate predicateWithFormat: @"name == %@",selectedExerciseName]];
    if ([filteredExercisesFromSession count] > 0)
    {
        self.exercise=[filteredExercisesFromSession anyObject];
    }
    else
    {
        self.exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:@"Exercise" inManagedObjectContext:managedObjectContext];
        self.exercise.name = selectedExerciseName;
        [session addExercisesObject:exercise];
    }

    if (![managedObjectContext save:&error])
    {
        // Handle the error.
    }
    NSLog(@"Save error: %@", error);

    [fetchRequest release];
    self.fetchedResultsController = nil;
    [setsTableView reloadData];
}

-(IBAction)createSet
{
    Set *set = (Set *)[NSEntityDescription insertNewObjectForEntityForName:@"Set" inManagedObjectContext:managedObjectContext];
    set.weight = [NSNumber numberWithFloat:weightSelected2];
    set.reps = [NSNumber numberWithInt:repSelected];
    set.timeStamp = self.picker.date;
    [self.exercise addSetsObject:set];

    NSError *error = nil;
    if (![managedObjectContext save:&error])
    {
        // Handle the error.
    }
    NSLog(@"error: %@", error);
    self.fetchedResultsController = nil;
    [setsTableView reloadData];
}

我正在尝试保持新代码与此不太相似,也许我可以调整一些事情而不是创建一些全新的代码。

编辑:

这是我到目前为止的一点点,有点卡住但仍在努力。感谢

//Session.h
@interface Session : NSManagedObject {

NSString * const kSessionLeavingActiveSession = @"kSessionLeavingActiveSession";
NSString * const kSessionChangingActiveSession = @"kSessionChangingActiveSession";

static Session *activeSession = nil;

//Session.h
@implementation Session

// a static method to retrieve & create if nil the active session
+ (Session *)activeSession {
    if (activeSession = nil)
    {
        session = (Session *)[NSEntityDescription insertNewObjectForEntityForName:@"Session" inManagedObjectContext:managedObjectContext];
    } 
}

+ (Session *)sessionForDate:(NSDate *)date andSetActive:(BOOL)isActive {

    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
    NSDateComponents *dateComponentsForToday = [calendar components:unitFlags fromDate:self.picker.date];
    [dateComponentsForToday setHour:0];
    [dateComponentsForToday setMinute:0];
    [dateComponentsForToday setSecond:0];
    NSDate *targetDateBegins = [calendar dateFromComponents:dateComponentsForToday]; 
    NSDate *targetDateEnds = [targetDateBegins dateByAddingTimeInterval:(60 * 60 * 24 - 1)];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat: @"(timeStamp >= %@ && timeStamp <= %@)", targetDateBegins, targetDateEnds]];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Session" inManagedObjectContext:managedObjectContext]];

    NSError *error = nil;
    NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    NSLog(@"Fetch error: %@", error);

    if ([results count])
    {
        session = (Session *)[results objectAtIndex:0];
        NSLog(@"Already have session for date: %@", session.timeStamp);
    }
    else
    {
        session = (Session *)[NSEntityDescription insertNewObjectForEntityForName:@"Session" inManagedObjectContext:managedObjectContext];
        session.timeStamp = self.picker.date;
        NSLog(@"New session for date: %@", session.timeStamp);
    }

    //send Notification kSessionChangingActiveSession if isActive == YES

    //if isActive is true, set it to the active session. 
}

+ (void)saveOrDestroyActiveSession {
    //register this function as an observer on kSessionChangingActiveSession
    //before the active session is changed, you will be able to determine
    //if the session has anything associated with it, and persist it, or 
    //destroy it.

    //determine if it has exercises assigned to it.

    //if it does, save the context.

    //if it doesn't destroy the active session and set activeSession to nil 
}


+ (void)saveActiveSession {
    //register this function as an observer on kSessionLeavingActiveSession.
    //If you are leaving an area of the application where you are working on
    //the session, you want to send this notification so that you can save
    //the session if you have added exercises.

    //you don't want to delete it though, if you can still go back to the
    //active session, for example, if it's the active session view controller
    //on a tab controller.
}

// the rest of your session methods

@end

//your app delegate
- (void)applicationWillResignActive:(UIApplication *)application {
    //send a notification that you are leaving the active session
}


//viewController.m
//modify your fetched results controller to pull it's list of exercises from the 
//active session, in case it's not saved you can still retrieve the exercises associated
//with it.

- (void)viewDidUnload {
    //send a notification that you are leaving the active session
}

- (void)createSession {
    Session *activeSession = [Session sessionForDate:self.picker.date andSetActive:YES];


    NSSet *filteredExercisesFromSession=[session.exercises filteredSetUsingPredicate:[NSPredicate predicateWithFormat: @"name == %@",selectedExerciseName]];
    if ([filteredExercisesFromSession count] > 0)
    {
        self.exercise=[filteredExercisesFromSession anyObject];
    }
    else
    {
        self.exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:@"Exercise" inManagedObjectContext:managedObjectContext];
        self.exercise.name = selectedExerciseName;
        [session addExercisesObject:exercise];
    }
    //if you've added exercises go ahead and save. 
    //if you haven't let the observers take care of persisting or destroying it.
}

1 个答案:

答案 0 :(得分:1)

这可能比我想写的要脏一些,但它应该让你对我如何解决问题的看法有所了解。

//Session.m
//Check out the link to PSFoundation and the ActiveRecord Core Data methods
//https://github.com/steipete/PSFoundation/tree/master/activerecord-coredata  

NSString * const kSessionLeavingActiveSession = @"kSessionLeavingActiveSession";
NSString * const kSessionChangingActiveSession = @"kSessionChangingActiveSession";

static Session *activeSession = nil;
@implementation Session

// ....

// a static method to retrieve & create if nil the active session
+ (Session *)activeSession {
    //if activeSession = nil create a new instance
    //reading the code it looks like you only create a new session if there 
    //isn't a session that already exists for the day chosen in the date picker?
    //If that's the case, then it is only possible for there ever to be
    //a single instance of an active session, one which is currently in view.   
}

+ (Session *)sessionForDate:(NSDate *)date andSetActive:(BOOL)isActive {
    //wrap all of your create session logic in here.
    //search for a session that exists for this date, and return it if
    //it exists, or create a new session if it doesn't.

    //send Notification kSessionChangingActiveSession if isActive == YES

    //if isActive is true, set it to the active session. 
}

+ (void)saveOrDestroyActiveSession {
    //register this function as an observer on kSessionChangingActiveSession
    //before the active session is changed, you will be able to determine
    //if the session has anything associated with it, and persist it, or 
    //destroy it.

    //determine if it has exercises assigned to it.

    //if it does, save the context.

    //if it doesn't destroy the active session and set activeSession to nil 
}


+ (void)saveActiveSession {
    //register this function as an observer on kSessionLeavingActiveSession.
    //If you are leaving an area of the application where you are working on
    //the session, you want to send this notification so that you can save
    //the session if you have added exercises.

    //you don't want to delete it though, if you can still go back to the
    //active session, for example, if it's the active session view controller
    //on a tab controller.
}

// the rest of your session methods

@end

//your app delegate
- (void)applicationWillResignActive:(UIApplication *)application {
    //send a notification that you are leaving the active session
}


//viewController.m
//modify your fetched results controller to pull it's list of exercises from the 
//active session, in case it's not saved you can still retrieve the exercises associated
//with it.

- (void)viewDidUnload {
    //send a notification that you are leaving the active session
}

- (void)createSession {
    Session *activeSession = [Session sessionForDate:self.picker.date andSetActive:YES];

    //code to add exercises to session
    //if you've added exercises go ahead and save. 
    //if you haven't let the observers take care of persisting or destroying it.
}