1

スライダーの値を示すラベルの横に、開始日に対応する日付+スライダーの値の単位での日数を表示したいと思います。

スライダーを動かすと、アプリがシミュレーターでクラッシュします。私が知る限り、新しい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
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 に答える