NSDate 分配初始化 &获取发送到已释放实例的消息

发布于 2024-11-26 18:14:05 字数 738 浏览 1 评论 0原文

我知道获取新 NSDate 的首选方式是 [NSDate date]。但我只是很困惑为什么下面的代码会抛出异常“消息发送到已释放的实例”

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];

此代码位于一个视图控制器中,该视图控制器被另一个视图控制器用作“虚拟”视图..类似于此: http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日记撕了你也走了 2024-12-03 18:14:05

您的第一个问题是您通过分配一个 NSDate 对象来声明 dateFromStr ,然后当您将第一次调用的结果分配给 dateFromStr:.您可以这样简化(并消除泄漏):

NSDate *dateFromStr = [dateFormatter dateFromString:self.releaseDate];

您需要知道的是您没有分配该对象,因此不需要释放它。除非您调用像 alloc 这样的方法(还有其他一些方法;搜索有关内存管理的其他帖子),那么您不负责释放该对象。

因此,在您发布的代码中,最后一行正在释放您未分配的对象并导致错误。

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.

独守阴晴ぅ圆缺 2024-12-03 18:14:05

而不是

NSDate *dateFromStr = [[NSDate alloc] init];
// produce date object
dateFromStr = [dateFormatter dateFromString:self.releaseDate];

你应该使用 just

NSDate *dateFromStr = [dateFormatter dateFromString:self.releaseDate];

否则你会覆盖该对象并丢失旧对象的地址。
之后,您尝试用手释放新的,然后垃圾收集器尝试释放它。而您的第一个分配的对象正在泄漏。

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.

烈酒灼喉 2024-12-03 18:14:05
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *dateFromStr = [[NSDate alloc] init];
// produce date object

这里您正在创建一个 dateFromStr,我们称他为“John”。

dateFromStr = [dateFormatter dateFromString:self.releaseDate];

[NSDateFormatter dateFromString] 将返回一个新对象“Tom”,该对象已被自动释放。您已经丢失了对已泄露的“John”的任何引用。

[dateFormatter setDateFormat:@"MM.dd.yyyy"];
NSString *strDate = [dateFormatter stringFromDate:dateFromStr];

[dateFormatter release];
[dateFromStr release];

在这里,您正在向已经[自动释放]的对象发送[释放]消息。最终结果是您将对“Tom”调用 [release] 两次,对“John”调用零次。

您可以像这样重写您的代码:

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];
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];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文