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.