views:

677

answers:

1

Next to a label showing the value of a slider i want to show the date that corresponds to a start date + the number of days in slider value units.

When i move the slider the app crashes in the Simulator. As far as i could find out that happens when i try to create a new NSDate field and my startDate object being "out of scope".

Reading a lot regarding retaining and releaseing NSDate documentation had not helped me until now, because the documentation is so abstract that it seems to me that I'm not able to find the relevant part(s) in the documentation. I hope to understand more by example.

So what's wrong with the following code (and from where in the documentation should a beginner have learned that) ?

#import <UIKit/UIKit.h>

@interface SliderDateViewController : UIViewController {
    UILabel *dateLabel;
    UILabel *sliderValueLabel;
    UISlider *slider;
    NSDate *startDate;

}

@property (nonatomic, retain) IBOutlet UILabel *dateLabel;
@property (nonatomic, retain) IBOutlet UILabel *sliderValueLabel;
@property (nonatomic, retain) IBOutlet UISlider *slider;
@property (nonatomic, retain) NSDate *startDate;

-(IBAction)sliderValueChanged:(UISlider *)theSlider;

@end


#import "SliderDateViewController.h"

@implementation SliderDateViewController

@synthesize dateLabel;
@synthesize sliderValueLabel;
@synthesize slider;
@synthesize startDate;

- (void)viewDidLoad {

    [super viewDidLoad];

    dateLabel.text = @"01.01.2010";

    sliderValueLabel.text = @"0";

    NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
    [inputFormatter setDateFormat:@"dd.MM.yyyy"];

    self.startDate = [inputFormatter dateFromString:dateLabel.text];

    NSLog(@"startDate: ", self.startDate.description);

    [inputFormatter release];

}

-(IBAction)sliderValueChanged:(UISlider *)theSlider {

    int sliderValueAsInt = (int)(theSlider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat:@"%d", sliderValueAsInt];
    sliderValueLabel.text = newText;
    [newText release];

    // Next line following the comment crashed with
    // *** -[CFDate release]: message sent to deallocated instance 0x3b07d10
    NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];

    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"dd.MM.yyyy"];

    dateLabel.text = [outputFormatter stringFromDate:newDate];
    [outputFormatter release];
    // [newDate release] // <- this was the error
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}


- (void)dealloc {
    [dateLabel release];
    [sliderValueLabel release];
    [slider release];
    [startDate release];
    [super dealloc];
}

@end
+1  A: 

Firstly, -addTimeInterval: is deprecated. Use -dateByAddingTimeInterval: instead.


NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
[startDate release];
startDate = newDate;
[newDate release];

Since -addTimeInterval: is not an +alloc/-copy/-create method, the newDate is owned by no one and you should not -release it. To obtain the ownership you need to

NSDate *newDate = [startDate addTimeInterval:86400 * sliderValueAsInt];
if (newDate != startDate) {
   [startDate release];
   startDate = [newDate retain];
}

which can be conveniently rewritten as

self.startDate = [startDate addTimeInterval:86400 * sliderValueAsInt];

Judging from the code logic, the startDate should be kept immutable. That means the startDate = newDate; stuff shouldn't appear at all. Delete the 3 lines below NSDate *newDate = [startDate ...]; and the code shall work fine.

KennyTM
I use the iPhone OS 3.1 library. There is no -dateByAddingTimeInterval:
Frank Martin
@Frank: Oops, sorry. Read the Mac OS X 10.6 doc set.
KennyTM
Simulator does not crash now (Yippee!), but dates skyrocket in the label. They don't decrease to the initial value when the slider goes to Zero.
Frank Martin
@Frank: Because `startDate` shouldn't be changed at all. See update.
KennyTM
@KennyTM: It crashes with *** -[CFDate release]: message sent to deallocated instance 0x3b07d10
Frank Martin
@Frank: Where does it crash?
KennyTM
@KennyTM: There was still a [newDate release] in the method. Sorry! Now it works :-)
Frank Martin
Helped me a lot, thank you KennyTM !
balexandre