我们应该手动释放NSDate吗?

时间:2011-05-19 05:16:45

标签: iphone ios objective-c

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

# 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?

4 个答案:

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