简体   繁体   English

每月更新coredata对象

[英]monthly update of coredata objects

in a current project i manage entities Month that contain information about passed month' and one of them of course stands for the current month. 在当前项目中,我管理的实体Month包含约一个月过去了”,其中一人的信息当然是指当前月份。

every month contains a number attribute, that acts as identifier for the year. 每个月都包含一个number属性,作为年份的标识符。 the attribute contains an NSNumber of type int32 , that identifies the month with the format: YYYYMM . 该属性包含一个NSNumber of type int32NSNumber of type int32 ,用于标识格式为YYYYMM so for example February 2011 has the attribute number = 201102 . 例如,2011年2月的属性number = 201102

in the application the user enters data, that is always afflicted with the current month. 在应用程序中,用户输入的数据总是受当前月份的影响。 the user does not have the ability to edit, delete, or add month data of passed month. 用户无法编辑,删除或添加已过月份的月份数据。

so my coredata holds 1 month for the current month that will be updated, and as many other objects as month have passed in which the user has entered data. 所以我的coredata在1 month保存了1 month月,将会更新,并且用户输入数据的月份已经过了许多其他对象。

i have a function 我有一个功能

-(void)archiveMonth:(NSNumber *)month;

in my DAO class, that creates a new month object in coredata or updates the current month if the passed NSNumber matches the current month. 在我的DAO类中,如果传递的NSNumber与当前月份匹配,则在coredata中创建新的month对象或更新当前月份。

here comes the tricky part 这是棘手的部分

every time the user opens the application for the first time in a new month, i need the application to archive all passed month that dont have a corresponding core-data object yet. 每当用户在新的月份第一次打开应用程序时,我需要应用程序存档所有没有相应核心数据对象的passed month

how i did it so far (for testing purposes) looks like that: 到目前为止我是如何做到的(出于测试目的)看起来像这样:

    NSDate *rootDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(10*365*24*60*60)];
    // somewhere in 2010 so to be sure to catch all passed month

    NSNumber *rootMonth = [dataHandler getMonthNumber:rootDate] ;
    NSNumber *iterator;   // acts as the monthnumber currently active in the loop
    int now = [dataHandler getMonthNumber:[NSDate date]].intValue;

    iterator = [NSNumber numberWithInt:rootMonth.intValue];
    while (now >= iterator.intValue) {
        iterator = [NSNumber numberWithInt:iterator.intValue+1];
        if (iterator.intValue%100 > 12) { //jump all invalid month numbers 

            while (iterator.intValue%100 != 1) {
                iterator = [NSNumber numberWithInt:iterator.intValue+1 ];
            }
        }

        NSArray *temp = [dataHandler fetchMonth:iterator];
        if (temp.count == 0) {                         
            //  no data = needs archive
            [dataHandler archiveMonth:iterator];
        }
    }

i have this in my factory that gets called at application start. 我在我的工厂有这个在应用程序启动时被调用。

questions this is very ugly and creates a lot of overhead 问题 这是非常丑陋的,并产生了很多开销

  • how can i determine if its the first time in the month the user opens the app so i dont have to archive every single time he starts the app? 如何判断用户是否在本月第一次打开应用程序,这样我每次启动应用程序时都不需要存档?
  • do any of you see a better way to iterate through passed month? 你们中的任何一个人看到了更好的方法来迭代过去一个月吗?
  • might there even be a way i dont have to fetch every month to determine if it already exists? 甚至可能有一种方法,我不必每个月取一次,以确定它是否已经存在?
  • can i somehow find out what was the last month archived, and start the iteration from there? 我可以以某种方式找出上个月归档的内容,并从那里开始迭代吗?

i would really appreciate some help, thanks in advance =) if you need any more code, or find something might be missing in the question, ill be happy to provide it. 我真的很感激一些帮助,提前谢谢=)如果你需要更多的代码,或者在问题中找不到某些东西,我很乐意提供它。

note this is a mockup code, that i used for testing, the question is not how to improve the code, but how to improve the algorithm =) 注意这是一个模型代码,我用于测试,问题不是如何改进代码,但如何改进算法=)

I would do it this way: 我会这样做:

  1. Run your monthly check and store the yyyyMM value to NSUserDefaults . 运行每月检查并将yyyyMM值存储到NSUserDefaults
  2. Every application launch, calculate the yyyyMM value for the current date and compare it to the value stored in NSUserDefaults . 每次启动应用程序,计算当前日期的yyyyMM值,并将其与NSUserDefaults存储的值进行比较。
  3. If it doesn't match, then it is a new month so run your monthly checks again. 如果它不匹配,那么这是一个新的月份,所以再次运行每月检查。

It looks like this: 它看起来像这样:

#define KEY_FOR_MONTHLY_LAST_CHECKED @"monthlyCheckedKey"

- (NSInteger)yyyyMMFromDate:(NSDate *)date {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyyMM"];

    NSString *yyyyMMString = [formatter stringFromDate:date];
    return [yyyyMMString intValue];
}

- (void)runMonthly {
    // This code is run once per month

    // Update NSUserDefaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setInteger:[self yyyyMMFromDate:[NSDate date]] forKey:KEY_FOR_MONTHLY_LAST_CHECKED];
    [defaults synchronize];
}

- (void)checkMonthly {
    NSUserDefaults *defaults    = [NSUserDefaults standardUserDefaults];
    NSInteger lastCheckedyyyyMM = [defaults integerForKey:KEY_FOR_MONTHLY_LAST_CHECKED];
    NSInteger currentyyyyMM     = [self yyyyMMFromDate:[NSDate date]];

    if (lastCheckedyyyyMM != currentyyyyMM) {
        [self runMonthly];
    }
}

All you have to do is add [self checkMonthly]; 你所要做的就是添加[self checkMonthly]; so that it runs every application launch. 以便它在每次应用程序启动时运行。

Also, I would change this: 另外,我会改变这个:

if (iterator.intValue%100 > 12) { //jump all invalid month numbers 
    while (iterator.intValue%100 != 1) {
        iterator = [NSNumber numberWithInt:iterator.intValue+1 ];
    }
}

To this: 对此:

if (iterator.intValue % 100 == 13) { //jump all invalid month numbers 
    iterator = [NSNumber numberWithInt:iterator.intValue+88];
}

It just adds 87 to the number when it hits 13 to change something like 201113 to 201201 当它达到13来改变像201113到201201这样的东西时,它只增加了87

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM