NSDate基本使用错误

时间:2010-02-17 16:34:33

标签: iphone xcode nsdate

在显示滑块值的标签旁边,我想显示与开始日期对应的日期+滑块值单位的天数。

当我移动滑块时,应用程序在模拟器中崩溃。据我所知,当我尝试创建一个新的NSDate字段并且我的startDate对象“超出范围”时会发生这种情况。

阅读很多关于保留和发布NSDate文档的内容直到现在都没有帮助我,因为文档是如此抽象,以至于在我看来我无法在文档中找到相关的部分。我希望通过实例了解更多。

那么下面的代码有什么问题(初学者应该从文档中的哪些地方学到这一点)?

#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 个答案:

答案 0 :(得分:2)

首先,不推荐使用-addTimeInterval:。请改用-dateByAddingTimeInterval:


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

由于-addTimeInterval:不是+alloc / -copy / -create方法,newDate不属于任何人,您不应该-release它。获得您需要的所有权

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

可以方便地重写为

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

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