开发者

NSDate alloc init & getting message sent to deallocated instance

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开发者_如何学Go 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];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜