我们应该手动发布 NSDate 吗?

发布于 2024-11-08 16:27:20 字数 3844 浏览 0 评论 0原文

我在头文件中使用以下配置声明了 NSDate:

# TestController.h
@interface TestController : UITableViewController{
    NSDate      *selectedDate;
    NSManagedObject *task;
}
    @property (nonatomic, retain) NSManagedObject *managedObject;
    @property (retain) NSDate *selectedDate 
@end

# TestController.m
@implementation TestController
    - (void)viewDidLoad {
        self.selectedDate = [managedObject valueForKey:@"title"];
    }
    - (void)viewDidUnload {
        self.task = nil;
        self.selectedDate = nil;
    }

    - (void)dealloc {
        [self.task release]
      [self.selectedDate release];
      [super dealloc];
    }
@end

据我了解,您应该释放分配、复制或保留的变量。由于我这里保留了变量数据,所以我在dealloc的时候释放。但是,最终抛出内存释放错误:

“[NSDate isNSDate]:消息发送到释放实例 0x6923750”

如果我没有手动释放它,它工作正常。我的问题是我应该释放这个场景的变量吗?

更新:

使用僵尸模板进行仪器测试,这是输出:

#   Category    Event Type  RefCt   Timestamp   Address Size    Responsible Library Responsible Caller
0   __NSDate    Malloc  1   1331055104  0x895e9d0   16  CoreData    -[NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:]
1   __NSDate    Retain  2   1333056000  0x895e9d0   0   Task    -[TaskViewCell configureData:]
2   __NSDate    Retain  3   3045008128  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
3   __NSDate    Retain  4   3054921984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
4   __NSDate    Release 3   3059244032  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
5   __NSDate    Release 2   3059607040  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
6   __NSDate    Retain  3   3715918848  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
7   __NSDate    Retain  4   3727657984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
8   __NSDate    Release 3   3730131200  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
9   __NSDate    Release 2   3730286080  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
10  __NSDate    Retain  3   4250617856  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
11  __NSDate    Retain  4   4250759936  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
12  __NSDate    Release 3   4250761984  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
13  __NSDate    Retain  4   4260489984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
14  __NSDate    Release 3   4263536896  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
15  __NSDate    Release 2   4263687168  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
16  __NSDate    Release 1   4656624128  0x895e9d0   0   Task    -[TaskEditController dealloc]
17  __NSDate    Retain  2   7570179840  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
18  __NSDate    Retain  3   7570360064  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
19  __NSDate    Release 2   7570361088  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
20  __NSDate    Retain  3   7577499136  0x895e9d0   0   CoreData    -[NSSQLRow copy]
21  __NSDate    Release 2   7602608128  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
22  __NSDate    Release 1   7602752256  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
23  __NSDate    Release 0   7971558144  0x895e9d0   0   Task    -[TaskEditController dealloc]
24  __NSDate    Zombie  -1  9697122048  0x895e9d0   0   Foundation  -[NSDateFormatter stringForObjectValue:]

不太明白这意味着什么。但是,我的猜测是 coredata 即使保留了 NSDate 也会释放它吗?

I declared NSDate at my header file with following configuration:

# TestController.h
@interface TestController : UITableViewController{
    NSDate      *selectedDate;
    NSManagedObject *task;
}
    @property (nonatomic, retain) NSManagedObject *managedObject;
    @property (retain) NSDate *selectedDate 
@end

# TestController.m
@implementation TestController
    - (void)viewDidLoad {
        self.selectedDate = [managedObject valueForKey:@"title"];
    }
    - (void)viewDidUnload {
        self.task = nil;
        self.selectedDate = nil;
    }

    - (void)dealloc {
        [self.task release]
      [self.selectedDate release];
      [super dealloc];
    }
@end

For my understanding, you should release variables that is alloc, copy or retain. As I retain the variable data here, so I release when dealloc. But, end up throw memory deallocation error:

"[NSDate isNSDate]: message sent to deallocated instance 0x6923750"

If I didn't manually release it, its working fine. My question is should I release the variable for this scenario?

Update:

Did an instrument test with zombie templates and this is the output:

#   Category    Event Type  RefCt   Timestamp   Address Size    Responsible Library Responsible Caller
0   __NSDate    Malloc  1   1331055104  0x895e9d0   16  CoreData    -[NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:]
1   __NSDate    Retain  2   1333056000  0x895e9d0   0   Task    -[TaskViewCell configureData:]
2   __NSDate    Retain  3   3045008128  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
3   __NSDate    Retain  4   3054921984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
4   __NSDate    Release 3   3059244032  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
5   __NSDate    Release 2   3059607040  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
6   __NSDate    Retain  3   3715918848  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
7   __NSDate    Retain  4   3727657984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
8   __NSDate    Release 3   3730131200  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
9   __NSDate    Release 2   3730286080  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
10  __NSDate    Retain  3   4250617856  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
11  __NSDate    Retain  4   4250759936  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
12  __NSDate    Release 3   4250761984  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
13  __NSDate    Retain  4   4260489984  0x895e9d0   0   CoreData    -[NSSQLRow copy]
14  __NSDate    Release 3   4263536896  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
15  __NSDate    Release 2   4263687168  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
16  __NSDate    Release 1   4656624128  0x895e9d0   0   Task    -[TaskEditController dealloc]
17  __NSDate    Retain  2   7570179840  0x895e9d0   0   CoreData    -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:]
18  __NSDate    Retain  3   7570360064  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
19  __NSDate    Release 2   7570361088  0x895e9d0   0   CoreData    -[NSManagedObject setValue:forKey:]
20  __NSDate    Retain  3   7577499136  0x895e9d0   0   CoreData    -[NSSQLRow copy]
21  __NSDate    Release 2   7602608128  0x895e9d0   0   CoreData    -[NSSQLOperation dealloc]
22  __NSDate    Release 1   7602752256  0x895e9d0   0   CoreData    -[NSKnownKeysDictionary1 dealloc]
23  __NSDate    Release 0   7971558144  0x895e9d0   0   Task    -[TaskEditController dealloc]
24  __NSDate    Zombie  -1  9697122048  0x895e9d0   0   Foundation  -[NSDateFormatter stringForObjectValue:]

Didn't really understand what this mean. But, my guess is coredata releasing the NSDate even with retain?

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

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

发布评论

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

评论(4

潦草背影 2024-11-15 16:27:20

解决过度释放对象问题的最佳方法是启动 Instruments(在 XCode 中,键入 ⌘-I 而不是 ⌘-R)并选择“Zombies”模板 - 它会显示每个对象的位置被保留和释放,并告诉您代码何时向已释放的实例发送消息。

在这种情况下,不平衡的释放可能潜伏在代码中的其他地方,并且将释放放入 dealloc 方法中会暴露其他地方的问题。无论如何,您的问题的直接答案是“是的,您应该释放您保留的变量”,并且您在此处发布的代码具有正确的保留与释放比率(即一对一),因此我会寻找您可能发布此 NSDate 的其他地方。

The best way to troubleshoot a problem with over-releasing an object is to fire up Instruments (from within XCode, type ⌘-I instead of ⌘-R) and choose the "Zombies" template – it'll show you where each object is being retained and released, and tell you when your code sends a message to an already-released instance.

It's possible in this case that an unbalanced release is lurking somewhere else in your code, and putting a release in your dealloc method is exposing a problem that lies elsewhere. In any case, the direct answer to your question is "yes, you should be releasing the variable you retained," and the code you've posted here has the correct ratio of retains to releases (that is, one to one), so I'd look for other places where you might be releasing this NSDate.

独木成林 2024-11-15 16:27:20

调用[ self.selectedDate release ]将减少self.selectedDate中对象的保留计数,但是self.selectedDate仍然包含对(现在过度释放)的引用日期对象。

您应该这样做:

self.selectedDate = nil

因为:

self.selectedDate = nil

对于此实际代码来说是方便的语法:

[ self setSelectedDate:nil ]

方法 setSelectedDate: 自动生成

@synthesize selectedDate

由于属性被声明为 retain,生成的 setter 如下所示:

-(void)setSelectedDate:(NSDate*)date
{
    [ selectedDate release ] ; // refers to the generated selectedDate instance variable in this class
    selectedDate = [ date retain ] ;
}

最后,如果您不需要原子访问(大多数情况下不需要),请使用此 nonatomic 声明改为:

@property ( nonatomic, retain ) NSDate * date

Calling [ self.selectedDate release ] will decrement the retain count of the object in self.selectedDate, however self.selectedDate still contains a reference to the (now over-released) date object.

You should do this:

self.selectedDate = nil.

Because:

self.selectedDate = nil

is convenient syntax for this actual code:

[ self setSelectedDate:nil ]

The method setSelectedDate: is automatically generated by

@synthesize selectedDate.

Since the property is declared retain, the generated setter looks like this:

-(void)setSelectedDate:(NSDate*)date
{
    [ selectedDate release ] ; // refers to the generated selectedDate instance variable in this class
    selectedDate = [ date retain ] ;
}

Finally if you don't need atomic access (which you don't in most cases), use this nonatomic declaration instead:

@property ( nonatomic, retain ) NSDate * date
独夜无伴 2024-11-15 16:27:20

是的,您应该释放您拥有的任何变量(分配、复制或保留)。然而,在 dealloc 方法中释放 NSDate 变量的正确方法应该是:

[selectedDate release];
selectedDate = nil;

self.selectedDate = nil;

第二种方法将调用属性的选择器方法,该方法首先释放变量,然后将 nil 分配给处理程序。因此,这行代码将释放它并将其设置为 nil,就像第一个选项中的两行单独的行一样。

Yes, you should release any variable that you own (alloced, copied or retained). However, the proper way to release your NSDate variable in dealloc method should be either:

[selectedDate release];
selectedDate = nil;

OR

self.selectedDate = nil;

The second approach will call the selector method of property which first releases the variable and then assign nil to the handler. So, this one line of code will both release it and set it to nil like the two separate lines in the first option.

草莓酥 2024-11-15 16:27:20

尝试

[selectedDate release];

代替

[self.selectedDate release];

Try

[selectedDate release];

Instead of

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