NSDate основная ошибка использования - PullRequest
1 голос
/ 17 февраля 2010

Рядом с меткой, показывающей значение ползунка, я хочу показать дату, соответствующую дате начала + количество дней в единицах измерения ползунка.

Когда я перемещаю ползунок, приложение симулируется. Насколько я мог узнать, что происходит, когда я пытаюсь создать новое поле 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 Ответ

2 голосов
/ 17 февраля 2010

Во-первых, -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; материал не должен появляться вообще. Удалите 3 строки ниже NSDate *newDate = [startDate ...];, и код будет работать нормально.

...