简体   繁体   中英

App runs on Simulator, not on device

I have this code that I have been re-using for years now. This year it broke, and I don't understand why. In my app, I use a calendar, that is using the KLDate class.

In that class, there is a method that looks like this:

- (id)initWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day {
    NSParameterAssert(1 <= month && month <= 12);
    NSParameterAssert(1 <= day   && day   <= 31);

    if (![super init])
        return nil;

    _year = year;
    _month = month;
    _day = day;

    return self;
}

If I run my app in the simulator, it works just fine. However, when I try and run it on my device, the app crashes, telling me

*** Assertion failure in -[KLDate initWithYear:month:day:], /.../Classes/Calendar/KLDate.m:79

and

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: 1 <= month && month <= 12'

I'm really puzzled. especially, because at some point the code actually WAS running on the device, possibly with a different provisioning profile.


OK, I searched a little deeper in the code, and found the place where things go wrong. At a specific moment, initWithYear is called with the wrong parameters:

- (id)initWithDate:(NSDate *)date {
    NSParameterAssert(date!=nil);
    NSInteger year, month, day;
    CFAbsoluteTime absoluteTime = CFDateGetAbsoluteTime((CFDateRef)date);
    CFCalendarRef calendar = CFCalendarCopyCurrent();
    CFCalendarDecomposeAbsoluteTime(calendar, absoluteTime, "yMd", &year, &month, &day);
    CFRelease(calendar);

    return [self initWithYear:year month:month day:day];
}

When running on the Simulator, the value for year is 2015 , as expected. Running the code on the device, the value is 4294969311 . So, somehow, the "CFCalendarDecomposeAbsoluteTime" doesn't like my device.

I hope you can help me; let me know if you need more information.

I'm guessing that you are getting some 64-bit warnings with this code.

NSInteger year, month, day;
…
CFCalendarDecomposeAbsoluteTime(calendar, absoluteTime, "yMd", &year, &month, &day);

The documentation for CFCalendarDecomposeAbsoluteTime says, "The type of all units is int."

In 64-bit code, NSInteger is not the same as int .

If you can, look for an updated version KLDate , or update your copy to fix the defect.

- (id)initWithDate:(NSDate *)date {
    NSParameterAssert(date!=nil);
    // NSInteger year, month, day;
    int year, month, day;
    CFAbsoluteTime absoluteTime = CFDateGetAbsoluteTime((CFDateRef)date);
    CFCalendarRef calendar = CFCalendarCopyCurrent();
    CFCalendarDecomposeAbsoluteTime(calendar, absoluteTime, "yMd", &year, &month, &day);
    CFRelease(calendar);

    return [self initWithYear:year month:month day:day];
}

By the way, while I'm glad you solved your problem, in addition to CFCalendarDecomposeAbsoluteTime , you might also consider NSCalendar method components:fromDate: :

- (instancetype)initWithDate:(NSDate *)date {
    NSParameterAssert(date);

    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];

    return [self initWithYear:components.year month:components.month day:components.day];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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