NSDate 保留消息发送到已释放的实例

发布于 2024-10-25 23:30:08 字数 874 浏览 1 评论 0原文

我在使用 NSDate 并将其保存在 NSUserDefaults 中时遇到了一些问题。看来每次 NSUserDefaults 保存我的 NSDate 时,它​​都不能,因为它被释放并在日志中显示此错误。

-[__NSDate retain]: message sent to deallocated instance 0x4c20c80

我知道 NSDate 的分配和释放方式与普通对象不同,但我想知道是否有人知道是否通过使用:

- (void)saveData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
[data setObject:dateOpened forKey:@"dateOpened"];
[dData synchronize];
}

...或者...

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
dateOpened = [data objectForKey:@"dateOpened"];
}

我正在释放我的 NSDate 实例,因此将其保留计数设置为 0所以我的应用程序在尝试时无法再次保存它?

我正在使用:

@property (retain) NSDate *dateOpened;

任何想法都会非常感激,因为我正在疯狂地试图解决这个问题。我只学习了大约 4 个月左右,我的第一个应用程序就快完成了,这是一个重要的工作!

非常感谢,如果您需要有关我正在做的事情的更多代码或信息,请告诉我。 :-D

I've been having some problems with NSDate and saving it in NSUserDefaults. It seams that every second time NSUserDefaults saves my NSDate, it can't because it is deallocated and shows this error in the log.

-[__NSDate retain]: message sent to deallocated instance 0x4c20c80

I know that NSDate allocs and deallocs in different ways to that of normal objects, but I was wondering if anyone knows if by using:

- (void)saveData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
[data setObject:dateOpened forKey:@"dateOpened"];
[dData synchronize];
}

...or...

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
dateOpened = [data objectForKey:@"dateOpened"];
}

i am releasing my instance of NSDate and so giving it a retain count of 0 so my app cant save it again when it tries?

I am using:

@property (retain) NSDate *dateOpened;

Any idea's would be much grateful as I am going nuts trying to figure this out. I've only been learning for about 4 months or so and am so nearly finished my first app and this is a major spanner in the works!

Thanks a lot, and if you need any more code or information on what I'm doing, please let me know. :-D

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

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

发布评论

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

评论(3

遇到 2024-11-01 23:30:08

就内存管理而言,NSDate 的行为与任何其他对象没有任何不同。您可能指的是,通常使用像 [NSDate date] 这样的便捷运算符来返回自动释放的对象(这意味着该对象将在主循环结束时(或每当自动释放池被释放时)被删除,除非另一个由于我看不到你的所有代码,所以我只能做出有根据的猜测,但我相信你正在对从 [data objectForKey:] 返回的对象调用release,这将是你的错误。一个自动释放的对象,因此在调用该对象之前,您不拥有该对象的“所有权”。如果您不对其调用保留,或显式分配它,则永远不应该对其调用释放(这适用于所有对象)。 )。

NSDate does not behave any differently than any other object as far as memory management goes. What you may be referring to is that it is common to use convenience operators like [NSDate date] that return an autoreleased object (meaning the object will be deleted at the end of the main loop (or whenever the autorelease pool is released) unless another class calls retain on it. Since I cannot see all of your code I can only make an educated guess, but I believe that you are calling release on the object returned from [data objectForKey:] and this would be your mistake. That function returns an autoreleased object and therefore you do not have "ownership" of the object until you call retain on it. If you do not call retain on it, or allocate it explicitly, you should never be calling release on it (this goes for all objects).

孤芳又自赏 2024-11-01 23:30:08

您遇到的问题出在您的 -loadData 方法中。

dateOpened = [data objectForKey:@"dateOpened"];

上面的行表示您直接访问 ivar,而不是通过将保留的属性。所以你有两个选择之一。

// First choice retain it yourself
dateOpened = [data objectForKey:@"dateOpened"];
[dateOpened retain];

或者

// Second choice have the @property do it for you
[self setDateOpened:[data objectForKey:@"dateOpened"]];

这就是为什么在私有 ivars 上使用下划线是个好主意,这样您就可以知道何时直接访问它们。你会犯很少的错误。 :)

// declaring it with underscore would have caught your mistake.
NSDate *_dateOpened;

The issue you are having is in your -loadData method.

dateOpened = [data objectForKey:@"dateOpened"];

Is the line above, you are accessing the ivar directly and not going thru the property which will retain. So you have one of two choice.

// First choice retain it yourself
dateOpened = [data objectForKey:@"dateOpened"];
[dateOpened retain];

Or

// Second choice have the @property do it for you
[self setDateOpened:[data objectForKey:@"dateOpened"]];

This is why it's a good idea to use underscores on your private ivars so you know when you are accessing them directly. You will have few mistakes. :)

// declaring it with underscore would have caught your mistake.
NSDate *_dateOpened;
倦话 2024-11-01 23:30:08

loadData 中的问题是您直接将 dateOpened 分配给自动释放的值,一旦事件循环通过,该值将无效。

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];

// dateOpened = [data objectForKey:@"dateOpened"];

// try:
   self.dateOpened = [data objectForKey:@"dateOpened"];

// which is basically the same as:
// [self setDateOpened:[data objectForKey:@"dateOpened"]];

// the following 2 lines could also work:
// [dateOpened release];
// dateOpened = [[data objectForKey:@"dateOpened"] retain];

}

如果您有 @synthesized dateOpened,那么您可以想象以下 2 个方法已添加到您的类中:

- (NSDate *)dateOpened {
  return dateOpened;
}

- (void)setDateOpened:(NSDate *)aDate {
  [aDate retain];
  [dateOpened release];
  dateOpened = aDate;
}

The problem in loadData is that you are directly assigning dateOpened to an autoreleased value, which will be invalid once the event loop passes.

- (void)loadData
{
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];

// dateOpened = [data objectForKey:@"dateOpened"];

// try:
   self.dateOpened = [data objectForKey:@"dateOpened"];

// which is basically the same as:
// [self setDateOpened:[data objectForKey:@"dateOpened"]];

// the following 2 lines could also work:
// [dateOpened release];
// dateOpened = [[data objectForKey:@"dateOpened"] retain];

}

If you have @synthesized dateOpened, then you can imagine that the following 2 methods have been added to your class:

- (NSDate *)dateOpened {
  return dateOpened;
}

- (void)setDateOpened:(NSDate *)aDate {
  [aDate retain];
  [dateOpened release];
  dateOpened = aDate;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文