我在头文件中使用以下配置声明了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
根据我的理解,您应该释放alloc,copy或retain变量。由于我在这里保留了变量数据,因此我在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?
答案 0 :(得分:3)
解决过度释放对象问题的最佳方法是启动Instruments(在XCode中,键入⌘-I而不是⌘-R)并选择“Zombies”模板 - 它会显示在哪里每个对象都被保留和释放,并告诉您代码何时向已发布的实例发送消息。
在这种情况下,可能会有一个不平衡的版本潜伏在代码中的其他位置,并且在dealloc方法中放置一个版本会暴露出其他地方的问题。在任何情况下,你的问题的直接答案是“是的,你应该发布你保留的变量”,你在这里发布的代码具有正确的保留与发布的比例(即一对一),所以我会寻找你可能会发布这个NSDate的其他地方。
答案 1 :(得分:2)
调用[ 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
答案 2 :(得分:1)
是的,您应该释放您拥有的任何变量(分配,复制或保留)。但是,在dealloc方法中释放NSDate变量的正确方法应该是:
[selectedDate release];
selectedDate = nil;
OR
self.selectedDate = nil;
第二种方法将调用属性的selector方法,该方法首先释放变量,然后将nil分配给处理程序。因此,这一行代码将释放它并将其设置为nil,就像第一个选项中的两个单独的行一样。
答案 3 :(得分:0)
尝试
[selectedDate release];
而不是
[self.selectedDate release];