Метод для помещения NSString и NSNumber в массив - PullRequest
1 голос
/ 14 января 2012

Это калькулятор. У меня есть дисплей, где я могу поставить цифры и переменные (х, у и т. Д.). Когда я нажимаю кнопку «Ввод», он отправляет то, что отображается в массиве, со всеми операндами.

Поскольку на дисплее может быть NSString (переменные) или NSNumber (цифры), я подумал использовать «id» в качестве аргумента метода.

- (IBAction)enterPressed 
{
   [self.brain pushOperand:self.display.text];
}

/////////////////////

- (void) pushOperand:(id)operand
{
    ////// So if operand is digit I need to transform it into NSNumber.

    NSNumber *digitToStack = [NSNumber numberWithDouble:operand];
    /////// Here is problem - "Sending '___strong id' to parameter of incompatible type 'double'

    NSNumber *digitToStack = [operand doubleValue];
    //////// If i do like this, i have warning - "Initializing 'NSNumber *__strong' with an expression of incompatible type 'double'

    [self.programStack addObject:operand];
}

Я не понимаю, о чем все эти предупреждения.

Итак, вопрос в том, могу ли я каким-то образом поместить в массив NSNumber и NSString, используя метод id, или как мне это сделать?

Могу ли я "преобразовать" аргумент из метода "id" в NSNumber?

1 Ответ

2 голосов
/ 14 января 2012

Да, вы можете "преобразовать" свой аргумент operand, но вам нужно будет выполнить приведение.

Также строка:

NSNumber *digitToStack = [NSNumber numberWithDouble:operand];

терпит неудачу, потому что "операнд" является объектом Objective C, в то время как эта функция ожидает тип double типа C (который является НЕ объектом Objective C).

Вот код, который я написал на макушке:

// Let's make operand always be a NSString object
// since that's what is being passed in from the label
- (void) pushOperand:(NSString *)operand
{
    double doubleValueFromOperand = [operand doubleValue];
    if(fabs(doubleValueFromOperand) != HUGE_VAL)
    {
        NSNumber *digitToStack = [NSNumber numberWithDouble:doubleValueFromOperand];
        if(doubleValueFromOperand != 0.0)
        {
            [self.programStack addObject:digitToStack];
            return;
        } else {
            // because NSString's doubleValue also returns 0.0 for a 
            // non-numerical string, let's make sure the input from the label
            // is not 0.0
            if([operand compare: @"0.0" options: NSCaseInsensitiveSearch range: NSMakeRange(0, 3)] == NSOrderedSame)
            {
                // the operand string *is* a 0.0 input, so let's add it to your stack and return
                [self.programStack addObject: digitToStack];
                return;
            }
        }
    }

    // if we get to this point, we probably have a non-numerical string object
    [self.programStack addObject: operand];
}

Этот код не был протестирован, не имеет гарантий и, безусловно, может использовать дальнейшую очистку и оптимизацию (например, проверка «0.0» - это не то, что я сам вставил бы в производственный код).

Но, надеюсь, этого достаточно, чтобы продвинуться дальше, Саша!

...