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 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
4

1 回答 1

2

首先,-addTimeInterval:已弃用。改为使用-dateByAddingTimeInterval:


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

因为-addTimeInterval:不是+alloc//方法,所以-copy不属于任何人,你不应该拥有它。要获得所有权,您需要-createnewDate-release

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

可以方便地重写为

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

从代码逻辑来看,startDate应该保持不可变。这意味着这些startDate = newDate;东西根本不应该出现。删除下面的 3 行NSDate *newDate = [startDate ...];代码应该可以正常工作。

于 2010-02-17T16:48:12.780 回答