【问题标题】:Objective-C calculations with values passed through segue not working使用通过 segue 传递的值的 Objective-C 计算不起作用
【发布时间】:2026-01-29 22:40:01
【问题描述】:

一个简单的问题,希望如此。为什么 lostWagesLabeltotalNeedLabel 得到 0 - 以下代码中计算的两个值?

编辑:原始问题完全替换为以下代码 - 根据目前收到的建议进行了更新:

三个值通过一个转场从父场景传递到该场景。当在此场景中显示为文本值时,所有三个值都会正确显示。但是当我运行 NSLog 时,只有一个值(周)正确显示 - 这意味着其他两个值将作为 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]]];
}

这里是所有东西都通过segue的地方:

- (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];
}

当我为earningsexpensesdisabled 使用尽可能少的 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

我也在尝试更改通过 segue 发送的内容的格式,并将其作为父场景中的声明:

@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;
    }
}

但是我在目标场景中收到了不兼容警告。

【问题讨论】:

  • 你调试了吗?这些数字是否被正确拉回?您是否从中获得了适当的浮点值?
  • 您能否提供一些可能在收入编号、费用编号和禁用编号中找到的示例值?
  • NSLog 记录这些变量的值并查看它们是什么。附带说明一下,如果您投射到 int 的值小于 0,它们将被截断为 0。
  • 应用程序编译没有错误。计算出的数字和其他数字都显示为正确格式 - 除了计算出的数字显示为 0 美元。可以为 EarningNumber 选择的值范围为 0 到 150,000,增量为 1,000;对于从 0 到 12,000 到 1,000 的费用数;并且对于 disabledNumber 从 0 到 52 的整数。我对 Xcode 还是很陌生。我还没有完成 NSLog。我会看看我是否能弄清楚如何。谢谢大家。
  • 为了节省时间 - 如果前 3 个值是 100,000、5,000 和 10;那么 2 个计算值应该是 19,230 和 11,538。

标签: objective-c xcode nsstring segue


【解决方案1】:

这里有很多问题。

首先,永远,永远,永远,使用float 或类似类型来表示货币或其他精确值。您在计算中得到错误的答案。这就是 NSDecimalNSDecimalNumber 的创建目的。

这就引出了另一个问题:你想用数学做什么?:

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

好的,您已经完成了一些浮点数学运算,然后将结果转换为int。 (通常您可能希望使用 NSInteger,但我们将把它放在一边。)这意味着任何小于 1 的值都将向下舍入为零,这可能是您的问题,具体取决于您的输入。 (我猜这就是你的问题所在;使用调试器检查你的值!)

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

那么,鉴于上述情况,当您拥有int 时,为什么还要使用+numberWithFloat:?我认为这不会自行中断,但仍然不是很正确。

顺便说一句,我猜您的整数文字(12 和 52)来自日历(每年 12 个月,每年 52 周)。如果不是,您可以忽略这一点,但如果是,那么这也是错误的:并非所有年份都有 52 周,并非所有年份都有 12 个月(对于月份的某些定义)。您不应该对这些值进行硬编码,而是根据需要使用各种 date and time functions 进行数学运算。

最后,如果你没有使用 ARC,你就会泄露commas

跟进

查看您更新的代码,我还有几个问题:

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

这是做什么的?您不只是设置回相同的值(尽管可能会引入一些不精确)吗?

destViewController.earningsNumber = self->earningsLabel.text;

不是访问对象的属性或实例变量的正确方法。 -> 取消引用结构指针的成员。您大概想使用self.earningsLabel[self earningsLabel]

最后,将视图与模型混合在一起通常是不明智的。例如,在这里您似乎使用标签文本作为支持数据的表示,然后强制进行大量类型转换等。最好有一个模型对象,可能使用NSDecimalNumber 作为后备存储,并从模型中更新您的视图。

【讨论】:

  • 使用 Xcode 4.3.2,Objective-C 自动引用计数设置为默认值 Yes。我担心这不是最正确或最简洁的代码。我一直在通过查找类似的示例和教程并对其进行修改以满足我的需要来开发该应用程序。到目前为止,我所做的计算结果都是正确的(尽管非常基本——比如 500 * 12 / 52)。没有任何事情最终会低于 1。您列出的第一个计算采用每月费用金额并以每周表示,然后乘以周值。对于这些计算,硬编码的数字可以正常工作。
  • 关于我使用的错误方法,我不会要求您正确重写它。但是,也许,您可以向我指出一些有用的参考资料。我找到的书籍和在线资料在这方面的帮助有限。
  • 第二个答案在哪里?我们在那里找到了一些东西,整个事情就消失了。 NSLog 显示值没有正确地转移到计算中,我请求帮助将在 segue 中转移的内容格式化为可以在公式中使用的东西。
  • @steveald 我猜回答者删除了它?无论如何,至于您上面的问题,我不确定您指的是哪些不正确的方法。大多数事情的黄金标准是类文档。例如,在developer.apple.com/library/mac/#documentation/Cocoa/Reference/…,您可以看到有一个您可能使用的+numberWithInt: 方法。
  • @steveald 我同意该代码现在可能可以工作,但并非所有年份都有 52 周 - 有关示例,请参阅 en.wikipedia.org/wiki/ISO_week_date