Я смог воспроизвести это самостоятельно; Вы столкнулись с интересным явлением.
Ваша проблема в том, что компилятор не видит определения для метода setAmount:
. В результате он не знает правильный тип аргументов, которые ожидает метод. В таких случаях компилятор предполагает, что все параметры имеют тип «...», а возвращаемые значения имеют тип «id». Но вы передаете CGFloat, а не «...».
Objective-C - это динамический язык, поэтому даже если компилятор не знает, существует ли целевой метод, он с радостью упакует параметры и попытается вызвать его в любом случае. Однако , на большинстве архитектур метод передачи параметров зависит от типа параметров. Целочисленные значения и параметры указателя обычно передаются в одном наборе регистров, а параметры с плавающей запятой - в другом, а структуры обычно передаются непосредственно в стек. (Точные детали зависят от того, на какой архитектуре вы работаете.) Поскольку компилятор не видит определения для метода setAmount:
, он предполагает, что параметры имеют тип ...
. В зависимости от архитектуры они могут передаваться в другом наборе регистров или даже в стеке.
Однако, когда метод setAmount:
выполняется, он ожидает, что переданные параметры будут в определенном наборе регистров. Конечно, они не были заполнены вызывающим абонентом и, таким образом, все еще установлены в 0. Вызывающий объект поместил новое значение в одном месте, но получатель посмотрел в другом. Не удивительно, что дела идут плохо.
Решение этого простое: добавьте #import "Custom.h"
вверху MainController.m
. Тогда компилятор сможет увидеть определение setAmount:
при компиляции MainController
, и, следовательно, будет знать, чтобы поместить новые значения в то место, где их ожидает получатель.
Кстати, держу пари, что когда вы компилировали, вы получали предупреждение; что-то вроде
warning: no '-setAmount:' method found
warning: (Messages without a matching method signature
warning: will be assumed to return 'id' and accept
warning: '...' as arguments.)
По крайней мере, это предупреждение, которое я получаю. Это был компилятор, который говорил вам, что он не знает, куда поместить параметры при выполнении этого вызова, поэтому он просто выбрал что-то и надеялся, что это сработает. В данном случае это не так.
Что касается правильной работы целых чисел и других типов, предположение компилятора о стиле передачи параметров как раз соответствует тому, что ожидал получатель. Это было просто удача.