Почему тип cast to id будет избавлен от этого сообщения об ошибке "Элемент коллекции типа" CGColorRef "(aka 'struct CGColor *) не является объектом Objective-C"

Вот код, о котором идет речь.

UIColor *colorOne = [UIColor colorWithRed:(120/255.0) green:(135/255.0) blue:(150/255.0) alpha:1.0];
UIColor *colorTwo = [UIColor colorWithRed:(57/255.0) green:(79/255.0) blue:(96/255.0) alpha:1.0];


CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;

gradient.colors = @[ [colorOne CGColor], [colorTwo CGColor] ]; // ERROR

В последней строке это сообщение об ошибке:

MyController.m:31:26: Collection element of type 'CGColorRef' 
 (aka 'struct CGColor *') is not an Objective-C object

Однако, если я изменю строку на

gradient.colors = @[ (id)[colorOne CGColor], (id) [colorTwo CGColor] ];

Это заставляет замолчать компилятор.

Почему работает ли тип struct с id? Это потому, что мы обманываем компилятор, struct тип struct стал классом без метода?

1 ответ

Он задокументирован в разделе "Переход к примечаниям о выпуске ARC":

Компилятор понимает методы Objective-C, возвращающие типы Core Foundation, следуя историческим соглашениям об именах Cocoa (см. <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i%23//apple_ref/doc/uid/10000011i" rel="nofollow noreferrer" target="_blank">Руководство по программированию в области управления памятью</a>). Например, компилятор знает, что в iOS CGColor, возвращаемый методом CGColor UIColor, не принадлежит. Вы все равно должны использовать соответствующий тип, как показано в этом примере:

<pre class="prettyprint linenums">NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]]; [colors addObject:(id)[[UIColor lightGrayColor] CGColor]]; </pre>

licensed under cc by-sa 3.0 with attribution.