开发者

Should we release NSDate manually?

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 releas开发者_运维技巧e 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?


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.


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


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.


Try

[selectedDate release];

Instead of

[self.selectedDate release];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜