i know the preferred way of get a new NSDate is [NSDate date]. but i'm just confused why the following code would ever throw the exception "message sent to deallocated instance"
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *dateFromStr = [[NSDate alloc] init];
// produce date object
dateFromStr = [dateFormatter dateFromString:self.releaseDate];
[dateFormatter setDateFormat:#"MM.dd.yyyy"];
NSString *strDate = [dateFormatter stringFromDate:dateFromStr];
[dateFormatter release];
[dateFromStr release];
this code is in a viewcontroller that is used as a "virtual" view by another viewcontroller..something similar to this: http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html
Your first problem is that you declare dateFromStr by allocating an NSDate object, then you leak that object when you assign the result of the first call to dateFromStr:. You could simplify (and eliminate the leak) thusly:
NSDate *dateFromStr = [dateFormatter dateFromString:self.releaseDate];
What you need to know about this is that you are not allocating this object, so you don't need to release it. Unless you call a method like alloc (and there are a couple others; search SO for other posts about memory management), then you are not responsible for releasing the object.
So in the code you posted, the last line is releasing an object you didn't allocate and causing your error.
Instead of
NSDate *dateFromStr = [[NSDate alloc] init];
// produce date object
dateFromStr = [dateFormatter dateFromString:self.releaseDate];
You should use just
NSDate *dateFromStr = [dateFormatter dateFromString:self.releaseDate];
Otherwise you overwrite the object and loose the address of the old one.
After that you're trying to release the new one by your hands, and then there's an attempt of garbage collector to release it. Whereas your first allocated object is leaking.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *dateFromStr = [[NSDate alloc] init];
// produce date object
Here you are creating a dateFromStr, let's call him "John".
dateFromStr = [dateFormatter dateFromString:self.releaseDate];
[NSDateFormatter dateFromString] will return a new object, "Tom", which has been already autoreleased. You have lost any reference to "John", which has leaked.
[dateFormatter setDateFormat:#"MM.dd.yyyy"];
NSString *strDate = [dateFormatter stringFromDate:dateFromStr];
[dateFormatter release];
[dateFromStr release];
Here you are sending a [release] message to an object which was already [autoreleased]. The end result is that you will have invoked [release] twice on "Tom", and zero times on "John".
You can rewrite your code like this:
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
// produce date object
NSDate *dateFromStr = [dateFormatter dateFromString:self.releaseDate];
[dateFormatter setDateFormat:#"MM.dd.yyyy"];
NSString *strDate = [dateFormatter stringFromDate:dateFromStr];
Related
I accessing a web service after i parsing that that code i got AiringTime of US EST 2011-10-17T14:00:00Z remaining code i written below
NSString *string = [[dateArray objectAtIndex:0] objectForKey:#"AiringTime"];
NSArray *stringArray1 = [string componentsSeparatedByString:#"T"];
NSString *string1 = [stringArray1 objectAtIndex:1];
NSArray *stringArray2 = [string1 componentsSeparatedByString:#"Z"];
NSString *dateInString = [stringArray2 objectAtIndex:0];
nowDate =[stringArray1 objectAtIndex:0];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm:ss"];
NSDate *dateFromString = [formatter dateFromString:dateInString];
[formatter release];
above NSDate *dateFromString given me appropriate output like 14:00 from morning to evening 6:30PM. After evening 6:30PM dateFromString gave mi nil value even though dateInString has an appropriate value?? Why? and How it happen?
I mean,
NSDate *dateFromString = [formatter dateFromString:dateInString];
this line not working, dateFromString gave me nil output.
I wasting my last 3 days evening time due to this strange problem. Please help me.
Thanks in advance.
See here, the example format is exactly the one you are dealing with.
Instead of splitting and manipulating the string yourself, simply do the following:
NSString *string = [[dateArray objectAtIndex:0] objectForKey:#"AiringTime"];
//Time in according to GMT+
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *dateFromString = [formatter dateFromString:string];
[formatter release];
If you are only interested in the time then NSDate is meaningless. What do you want to do with it afterwards?
I have a string with this data:
2011-09-13 22:20:00
I want to have this data:
13.09.2011
Additional I want to have the string "Today" when the date is today.
How to do this in Objective C?
I tried it the last 1 hour, but don't get it:
//Date basteln
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd"];
NSString* str = [[ens objectForKey:#"datum_server"] substringToIndex:10];
NSLog(#"%#", str);
NSDate *now = [dateFormat dateFromString:str];
NSLog(#"%#", now);
[dateFormat setDateFormat:#"dd.MM.yyyy"];
NSString *theDate = [dateFormat stringFromDate:now];
[dateFormat release];
[now release];
So I tried to cut of the time, convert it with the wrong format to the right format.
But it crashed in a SIGBART.
Ideas?
Don't release
now
This is an autoreleased object, you are over releasing it and this is causing your crash.
You should always release those object which you own it by using 'init', 'copy' 'alloc', 'new', 'copy', or 'mutableCopy'. so there you do not need to release the date object because you did not own that.
I am trying to clean up memory leaks and other issues in an existing iPhone app. I am a little new to Objective C, but have some good programming fundamentals and a general understanding of the memory management that is required when dev'ing iphone apps. My question is about the following method below.
-(NSDate *)formatDate:(id)value{
NSLog(#"eja: DetailViewController/ formatDate()");
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.S"];
[dateFormatter release];
return [dateFormatter dateFromString:value];
}
It is returning an error reading "Referenced-counted object is use after it is released". I see that dateFormatter is being freed before it is returned/used. The issue is of course that if you put the release after the return statement you get a 'Potential leak of an object' error associated with dateFormatter var declaration.
I also tried "autorelease"
return [[dateFormatter dateFromString:value] autorelease];
But I then get the error 'Object sent - autorelease too many times'.
Any words of advice on how to write this properly so the variables are properly managed?
Replace
[dateFormatter release];
with
[dateFormatter autorelease];
and it should work!
You can create an NSDate before you release the NSDateFormatter:
-(NSDate *)formatDate:(id)value
{
NSLog(#"eja: DetailViewController/ formatDate()");
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.S"];
NSDate *date = [dateFormatter dateFromString:value];
[dateFormatter release];
return date;
}
This way, your allocated NSDateFormatter gets released as it should while the object you are returning doesn't require manual memory management.
Instead of writing [dateFormatter release], you can autorelease it, and even save a line of code in the process.
- (NSDate *)formatDate:(NSString *)value {
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.S"];
return [dateFormatter dateFromString:value];
}
First one:
+ (NSDate*)convertToUTC:(NSDate*)sourceDate
{
NSTimeZone* currentTimeZone = [NSTimeZone localTimeZone];
NSTimeZone* utcTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:sourceDate];
NSInteger gmtOffset = [utcTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval gmtInterval = gmtOffset - currentGMTOffset;
return [NSDate dateWithTimeInterval:gmtInterval sinceDate:sourceDate];
}
Yes, I know this next one is strange but my server gives me a whack date format
+(NSDate *)getDateFromString:(NSString *)dtStr
{
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[inputFormatter setLocale:locale];
[locale release];
[inputFormatter setDateFormat:#"MMMM, dd yyyy HH:mm:ss"];
NSDate *formatterDate = [[inputFormatter dateFromString:dtStr] copy];
[inputFormatter release];
return formatterDate;
}
The first one doesn't, but the second one does, because you created a copy and didn't autorelease it. If you don't release it later, it will be leaked.
I don't see why you're even copying the date in the second method. Just cut that out and that will fix the leak.
You really should read (or re-read) the Memory Management Programming Guide for Cocoa, as it seems you need to refine your understanding of the memory-management rules.
I have this code that simple returns Today's date as a string formatted:
+(NSString*) getTodayString_YYYY_MM_DD {
NSDate * today = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
return [[formatter stringFromDate:today] autorelease];
}
With instruments I'm not getting a memory leak, but when I Analyze, XCode says:
Object sent -autorelease too many times
If I understand correctly, I have to release manually the formatter as I'm creating it using 'alloc', but I can't release here because I have to return the value, so I add the autorelease.
How I can do it better to improve it ?
thanks,
r.
You are -autoReleasing the NSString, not the formatter.
You don't need an autoRelease since -stringFromDate: is giving you an already autoReleased string.
Here is one way your code can look like:
+(NSString*) getTodayString_YYYY_MM_DD {
NSDate * today = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSString *retString = [formatter stringFromDate:today];
[formatter release];
return retString;
}
Given that an NSDate's description is always in the format YYYY-MM-DD HH:MM:SS ±HHMM:
+ (NSString *) getTodayString_YYYY_MM_DD
{
return [[[NSDate date] description] substringToIndex:10];
}
Just throwing it out there. It's probably less efficient than the NSDateFormatter method.