开发者

NSDate basic usage error

Next to a label showing the value of a slider i want to show the date that corresponds to a st开发者_Go百科art 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 releasing 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


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.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜