0

簡単な質問です。次のコードで計算された 2 つの値のlostWagesLabeltotalNeedLabelが0になるのはなぜですか?

編集:元の質問は次のコードに完全に置き換えられました-これまでに受け取った提案に基づいて更新されました:

親シーンからこのシーンへのセグエを介して 3 つの値が渡されます。このシーンでテキスト値として表示される場合、3 つの値はすべて正しく表示されます。しかし、NSLog を実行すると、値の 1 つ (週) のみが正しく表示されます。これは、他の 2 つの値が 0 として計算されることを意味します。

親シーンでの宣言は次のとおりです。

IBOutlet UISlider *earningsSlider;
IBOutlet UILabel *earningsLabel;
IBOutlet UISlider *disabledSlider;
IBOutlet UILabel *disabledLabel;
IBOutlet UISlider *expensesSlider;
IBOutlet UILabel *expensesLabel;

そして、ここに実装のサンプルがあります:

- (IBAction)earningsSlide:(id)sender {
    NSNumberFormatter *commas = [NSNumberFormatter new];
    commas.numberStyle = NSNumberFormatterDecimalStyle;
    int earningsValue = (int)(earningsSlider.value / 1000.0);
    [earningsSlider setValue:earningsValue * 1000.0];
    earningsLabel.text = [NSString stringWithFormat:@"$%@", 
                         [commas stringFromNumber:[NSNumber numberWithFloat:earningsValue * 1000]]];
}

すべてがセグエを通過する場所は次のとおりです。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"DisabilitySegue"]) {
        DisabilityViewController *destViewController = segue.destinationViewController;
        destViewController.earningsNumber = self->earningsLabel.text;
        destViewController.expensesNumber = self->expensesLabel.text;
        destViewController.disabledNumber = self->disabledLabel.text;
    }
}

新しいシーンの宣言は次のとおりです。

@property (nonatomic, strong) IBOutlet UILabel *earningsLabel;
@property (nonatomic, strong) NSString *earningsNumber;
@property (nonatomic, strong) IBOutlet UILabel *expensesLabel;
@property (nonatomic, strong) NSString *expensesNumber;
@property (nonatomic, strong) IBOutlet UILabel *disabledLabel;
@property (nonatomic, strong) NSString *disabledNumber;
@property (nonatomic, strong) IBOutlet UILabel *message;
@property (nonatomic, strong) NSString *lostWages;
@property (nonatomic, strong) IBOutlet UILabel *lostWagesLabel;
@property (nonatomic, strong) NSString *totalNeed;
@property (nonatomic, strong) IBOutlet UILabel *totalNeedLabel;

そして、現在の状態での実装は次のとおりです。

- (void)viewDidLoad
{
    NSNumberFormatter *commas = [NSNumberFormatter new];
    commas.numberStyle = NSNumberFormatterDecimalStyle;
    earningsLabel.text = earningsNumber;
    expensesLabel.text = expensesNumber;
    disabledLabel.text = disabledNumber;
    int earn = [earningsNumber intValue];
    int expense = [expensesNumber intValue];
    int weeks = [disabledNumber intValue];
    NSLog(@"%d %d %d",earn,expense,weeks);
    //print values to console
    int lost = (int)(earn / 52 * weeks);
    int need = (int)(expense * 12 / 52 * weeks);
    NSLog(@"%d %d",lost,need);
    //print values to console
    lostWages = [NSString stringWithFormat:@"$%@",
                        [commas stringFromNumber:[NSNumber numberWithInteger:lost]]];
    totalNeed = [NSString stringWithFormat:@"$%@",
                        [commas stringFromNumber:[NSNumber numberWithInteger:need]]];
    lostWagesLabel.text = lostWages;
    totalNeedLabel.text = totalNeed;

    [super viewDidLoad];
}

親シーンで収益費用、および無効() に1000、100 & 1 の可能な限り最小の金額を使用して実行すると、NSLog は次のようになります。

2012-08-17 09:01:38.277 MyApp[8117:15203] 0 0 1

2012-08-17 09:01:38.279 MyApp[8117:15203] 0 0

また、これを親シーンの宣言として使用して、セグエを介して送信される形式を変更しようとしています。

@interface IncomeProtectionViewController : UIViewController {

    IBOutlet UISlider *earningsSlider;
    IBOutlet UISlider *expensesSlider;
    IBOutlet UISlider *disabledSlider;
    IBOutlet UILabel *earningsLabel;
    IBOutlet UILabel *expensesLabel;
    IBOutlet UILabel *disabledLabel;
    NSNumber *earningsNumber;
    NSNumber *expensesNumber;
    NSNumber *disabledNumber;
}

そして、これは実装で:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"DisabilitySegue"]) {
        DisabilityViewController *destViewController = segue.destinationViewController;
        destViewController.earningsNumber = self->earningsNumber;
        destViewController.expensesNumber = self->expensesNumber;
        destViewController.disabledNumber = self->disabledNumber;
    }
}

しかし、目的のシーンで非互換性の警告が表示されます。

4

1 に答える 1

4

ここには多くの問題があります。

まず、絶対に、絶対に、通貨またはその他の正確な値に類似の型を使用します。計算で間違った答えが出ますfloat。これは、対処するために作成されたものです。NSDecimalNSDecimalNumber

これは別の質問につながります: あなたは数学で何をしようとしていますか?:

int need = (int)(expense * 12 / 52 * weeks);

OK、浮動小数点演算を行ったので、結果を にキャストしintます。(通常、おそらく NSInteger を使用したいと思うでしょうが、それは脇に置いておきます。) これは、1 未満の値がゼロに切り捨てられることを意味します。これは、入力によっては、すぐに問題になる可能性があります。(私の推測では、これが問題の原因です。デバッガを使用して値を調べてください!)

totalNeed = [NSString stringWithFormat:@"$%@",
                    [commas stringFromNumber:[NSNumber numberWithFloat:need]]];

では、上記に照らして、なぜ ? を使用+numberWithFloat:しているのintですか? これが自然に壊れるとは思いませんが、それでも実際には正しくありません。

余談ですが、あなたの整数リテラル (12 と 52) はカレンダー (年間 12 か月、年間 52 週間) から来ていると推測しています。そうでない場合はこれを無視できますが、そうである場合はこれも間違っています。すべての年が 52 週であるとは限らず、すべての年が 12 か月であるとは限りません (月の定義によっては)。このような値をハードコードするべきではありませんが、必要に応じてさまざまな日付と時刻の関数を使用して計算してください。

最後に、ARC を使用していない場合は、リークしていcommasます。

ファローアップ

更新されたコードを見て、さらにいくつか質問があります。

int earningsValue = (int)(earningsSlider.value / 1000.0);
[earningsSlider setValue:earningsValue * 1000.0];

これは何をするためのものですか?同じ値を元に戻しているだけではありませんか (ただし、不正確さが導入される可能性があります)。

destViewController.earningsNumber = self->earningsLabel.text;

これは、オブジェクトのプロパティまたはインスタンス変数にアクセスする正しい方法で はありません。->構造体ポインターのメンバーを逆参照します。self.earningsLabelおそらくorを使用したいでしょう[self earningsLabel]

最後に、一般的に、ビューとモデルを混在させることはお勧めできません。たとえば、ここでは、バッキング データの表現としてラベル テキストを使用しているように見えます。これにより、とりわけ多くの型変換が強制されます。おそらくNSDecimalNumberバッキングストレージに使用するモデルオブジェクトを用意し、モデルからすべてのビューを更新することをお勧めします。

于 2012-08-15T19:38:27.977 に答える