- [Not A Type retain]: сообщение отправлено на освобожденный экземпляр - PullRequest
18 голосов
/ 03 ноября 2011

Я преобразовал свое приложение для использования ARC.

Ранее у меня была следующая строка кода:

NSArray *colors = [NSArray arrayWithObjects:startColor, endColor, nil];

Поскольку неявное преобразование типа указателя без Objective-C в'id' запрещен с ARC, я переписал строку следующим образом:

NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];

На симуляторе все работает нормально, однако на устройстве приложение вылетает на упомянутой строке с сообщением об ошибке:

-[Not A Type retain]: message sent to deallocated instance

Есть идеи, как ее решить?

Ответы [ 3 ]

30 голосов
/ 03 ноября 2011

Это связующее соединение может не сработать, как описал hatfinch в его ответ здесь , потому что CGColorRef, возвращенный из -CGColor, может не зависать после вашей последней ссылки на UIColor, который его генерирует. Я думал, что это ошибка, основанная на обсуждении в этой ветке форума разработчиков Apple , но это было неправильное прочтение того, как управлять временем жизни этих CGColorRefs.

Одним из способов, с помощью которого это будет работать, является использование встроенного моста, предоставляемого методом -CGColor в UIColor. Вместо сохранения вашего CGColor во временную переменную, как вы делали выше, вы должны использовать что-то вроде следующего:

NSArray *colors = [NSArray arrayWithObjects:(id)[color1 CGColor],
                                            (id)[color2 CGColor], nil];

с color1 и color2 в качестве экземпляров UIColor.

Для мостов используется метод -CGColor, согласно разделу «Компилятор обрабатывает объекты CF, возвращенные из методов какао» в Переход к примечаниям к выпуску ARC . В документации в настоящее время отсутствует приведённый выше приведённый тип, который необходим для компиляции.

Я проверил это, и, похоже, в моем случае это работает, совпадая с тем, что Бен сообщает в вышеупомянутой ветке Форумы разработчиков.

В дополнение к вышесказанному, вы можете явно сохранить и освободить CGColorRefs, возвращенные из метода -CGColor, и соединить их через NSArray, опять же, как показано в шапке здесь .

0 голосов
/ 13 февраля 2013

Спасибо @Brad за отзыв -CGColor!

сбой моего приложения в следующей строке, которая будет вызываться объектом NSInvocation.

    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);

Временное решение - определить свойство цвета и использовать его вместо этого.

    @property(strong, nonatomic) UIColor *backgroundColor;
    ......
    self.backgroundColor = [UIColor whiteColor];
    ......
    CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
0 голосов
/ 03 ноября 2011

Edit:
Если вы используете свойство CGColor UIColor, CGColor исчезнет в тот момент, когда вы в последний раз ссылаетесь на экземпляр UIColor. Чтобы избежать этого, «соедините» ваши цвета непосредственно в вызове функции:

NSArray *colors = [NSArray arrayWithObjects:[uiStartColor CGColor], [uiEndColor CGColor], nil];

Этот метод описан в документации Apple

Оригинал:
попробуйте присвоить переменную: id color = (__bridge_transfer id)CGColorCreate(...); и больше ничего не делать с прямым возвращаемым значением CGColorCreate ()

...