I try to get the last modification date of a file:
NSFileManager *fm = [[NSFileManager alloc] init];
NSError *err;
NSDate *lastModif = [[fm attributesOfItemAtPath:filename error:&err] objectForKey:NSFileModificationDate];//filename is ok ;-)
if(err == nil) {
[lastModif retain];
//I can put a NSLog of lastModif here, it works !!
NSTimeInterval lastModifDiff = [lastModif timeIntervalSinceNow];//crash here
}
I don't understand why the NSDate seems to be released, why the retain does not retain it.
Thank you if you have any idea...
You don't need to retain lastModif. I think you might be trying to treat lastModifDiff as an object of some sort when you do an NSLog with it or whatever you do with it afterwards. NSTimeInterval is a typedef to a double so you need to treat it as a double or [NSNumber numberWithDouble:lastModifDiff] if you want to use it like an object.
I'm having the same problem, but this post seemed germane:
NSDate : timeIntervalSinceNow crash
I'm writing a simple set of functions- startClock/endClock -using NSDate to determine FPS in my game loop. Except that timeIntervalSinceNow crashes, claiming that my earlier set NSDate object doesn't exist.
I know for a fact that the NSDate object has a retain count of 1 when I call startClock, but my theory is that NSDate instances are internally rigged to auto-release when they get bored and aren't feeling useful.
Using retain/release to assume ownership of these flighty and ephemeral NSDate objects worked for me.
Related
I have an allocated object where its attributes are store in the following memory places:
When I make a simple attribution of the NSDate attribute to a variable it gives me an EXEC_BAD_ACESS.
As you can see from the first image only the date attribute and the fileDate variable have different addresses.
Am I making some pointer related error?
The other 2 attributes are assigned correctly to the variables, it only happens with the NSDate so maybe I'm missing some detail about NSDate.
EDIT1
DownloadFile definition:
EDIT2
init function:
EDIT3
date parameter:
Is there any reason why you are not using ARC? There are quite a few memory management errors there causing leaks and one that should cause your crash.
NSDate *dateFromString = [dateFormatter dateFromString:receivedDate];
returns an autoreleased NSDate so when you then call the additional
[dateFromString autorelease];
you are overreleasing the NSDate hence your crash.
[pFile setDate:[[NSDate alloc] init]];
is a memory leak. Going through the setter setDate: will cause pFile to take a +1 retain on the date, which it should release in it's dealloc. The [[NSDate alloc] init] call returns a date object with +1 but is then never released elsewhere.
You can fix this either with
[NSDate date]
Or
[[[NSDate alloc] init] autorelease];
The first option is preferred
I have built one 'deep' NSMutableDictionary that contains parsed XML data along with other relevant information that I can pass from one view controller to another. The NSMutableDictionary contains mostly NSStrings but also another NSMutableDictionary more NSStrings and finally followed even deeper with an NSMutableArray of custom objects (it's for a calendar).
Now, because it is a calendar, there are obviously dates involved. The XML data that I receive and parse using NSXMLParser returns strings, so it was on me to convert the day's date to usable numbers. The date in XML comes in with the following format: "MM.DD" I created the following method to do so:
- (void)createDateCodesWithString:(NSString *)string
{
NSInteger monthCode;
NSInteger dayCode;
....
NSArray *dates = [string componentsSeparatedByString:#"."];
monthCode = [[dates objectAtIndex:0] integerValue];
dayCode = [[dates objectAtIndex:1] integerValue];
....
shortDay = [NSNumber numberWithInt:dayCode];
}
'shortDay' is a NSNumber* and an ivar and set as a property (nonatomic, retain) for the custom object that I have created. When I run NSLog commands in the console, it appears that 'shortDay' and other data has been stored successfully in the deep NSMutableDictionary. I run in to problems, however, when I try to access the data again. When I access a NSString* stored ivar, things work OK, but when I attempt to access the NSNumber* I am given the error EXC_BAD_ACCESS with either code 1 or code 2. This is how I try to call upon the NSNumber*
NSNumber *number = day.shortDay;
return [number stringValue];
Might the problem be because the NSArray *dates strips the string into month and day strings and the day string, being two characters long, may contain a '0' before, say, a '6' if the day is the 6th of the month? Any advice?
I am happy to post more code if needed.
It's possible that the memory for shortDay is being cleaned up before the next time you try to access it. When assigning it, try this instead:
shortDay = [[NSNumber numberWithInt:dayCode] retain];
to increase the reference count (AKA take ownership of the object) to avoid the memory being deallocated too early.
If this resolves the problem, you will then need to call [shortDay release] in the dealloc method of your class, such that the memory for it will be properly deallocated at the right time.
The mysteries of Objective-C plague me yet again.
I have a string. It's defined in a header file called "Common.h".
If I give it a value thusly:
_DATESTRING = #"2011-08-16";
There is no problem, and it sticks around forever, however, if I do this:
_DATESTRING = [format stringFromDate:[NSDATE dateWithTimeIntervalSinceNow:0]];
I get a "message sent to deallocated instance" further down the pipes.
Why?
// This is a string that's not going to be released
_DATESTRING = #"2011-08-16";
// This is a string that's autoreleased
_DATESTRING = [format stringFromDate:[NSDATE dateWithTimeIntervalSinceNow:0]];
// You want somethhing like this
_DATESTRING = [[format stringFromDate:[NSDATE dateWithTimeIntervalSinceNow:0]] retain];
In short, if your method name contains alloc, copy, new or mutableCopy you have to release it yourself. Otherwise it's already autoreleased so if you want to keep it around you need to retain it.
Where exactly is down the pipes?
The method stringFromDate: returns an autorelease object, so I'm quite sure that it's getting automatically deallocated when you want to use it. It doesn't happens with string literals because these do not follow the standard memory management conventions for objects.
You may want to add a retain message:
_DATESTRING = [[format stringFromDate:
[NSDATE dateWithTimeIntervalSinceNow:0]] retain];
because -stringFromDate: returns autoreleased object. If you want it to stick around forever, you need to send -retain message to it, that is:
_DATESTRING = [[format stringFromDate:[NSDATE dateWithTimeIntervalSinceNow:0]] retain];
I have Question related to nsdate declaration.
NSDate *sortDate;
#property(nonatomic,retain) NSDate *sortDate;
#synthesize sortDate;
sortDate=[NSDate date];
I assign NSdate field in my class with above Procedure.I successfully assign value to my NSDATE(sortarray).Whaen when i retrieve its value's App craches with this message.
"malloc double free/non- aligned pointer being freed set a breakpoint in malloc_error_break to debug"
Give excess bad error.Some time it show,
When i remove NSDATE field from my class.App Run successfully.
Any thing wrong regarding declaration?
Any Solution.
Thanks in advance.
The date instance you get is autoreleased and not owned by you. If you assign directly to the ivar you have to take ownership, e.g.:
sortDate = [[NSDate date] retain];
It's usually better though to use the declared property, which takes care of that for you:
self.sortDate = [NSDate date];
Don't forget to relinquish ownership on dealloc, e.g.:
self.sortDate = nil;
See the Cocoa memory management rules and the declared properties documentation.
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
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).
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;
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;
}