【问题标题】:Passing CGColorRef as a value in KVC/KVO将 CGColorRef 作为 KVC/KVO 中的值传递
【发布时间】:2011-05-08 20:03:13
【问题描述】:

我正在使用 Opacity 生成我所有的 Quartz2D 图稿,我现在正在解决通过 KVC/KVO 更改颜色的问题。 Opacity 将其所有颜色变量定义为@dynamic,并将其自己的访问器实现为类定义的一部分。

我的问题是;如何通过键值传递新的 CGColorRef 值?

到目前为止(作为测试平台)我已经做到了这一点:

// Testbed ... Testbed ... Testbed ... Testbed ... Testbed ... Testbed ... Testbed ...
      CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
      CGFloat components[4] = {1.0f, 1.0f, 1.0f, 1.0f};
      CGColorRef color = CGColorCreate(space, components);

      [myCALayerReceiverObject setValue: color forKey: @"numColour"];
// Testbed ... Testbed ... Testbed ... Testbed ... Testbed ... Testbed ... Testbed ...

颜色空间和创建代码是直接从 Opacity 的 CALayer 类生成器中提取的(我还没有那么高级),但是传递 'color' 作为值会导致 iPhone 模拟器崩溃,并且 XCode 给了我一个非常神秘的警告;

“不兼容的指针类型将'CGColorRef'(又名结构'CGColor *')发送到'id'类型的参数”。

如何包装 CGColorRef 以通过 KVC 将其传递给接收器? 提前致谢。

【问题讨论】:

    标签: iphone quartz-graphics opacity key-value-observing key-value-coding


    【解决方案1】:

    将 CGColorRef 转换为 (id) 有效。这是一个将阴影设置为黑色的示例:

    [layer setValue:(id)[UIColor blackColor].CGColor forKey:@"shadowColor"];
    

    【讨论】:

      【解决方案2】:

      我本来建议使用NSValue 来包装你的颜色对象,但在测试过程中我得出的结论是 KVO/KVC 不适用于 CGColors。根据Key-Value Coding Programming Guide,原始类型和结构使用 NSValue 或 NSNumber 包装。但是,当尝试访问 CGColorRef 属性时,我得到一个“不符合 KVC”的异常。似乎指向结构的指针不像结构本身那样包装到 NSValues。这是我的测试代码:

      @interface MyClass : NSObject {
          CGColorRef color;
      }
      @property (assign) CGColorRef color;
      @end
      
      @implementation MyClass
      - (CGColorRef)color { return color; }
      - (void)setColor:(CGColorRef)newColor { color = newColor; }
      @end
      
      int main(int argc, char **argv) {
          NSAutoreleasePool *p = [NSAutoreleasePool new];
          MyClass *theObject = [MyClass new];
          CGColorRef theColor = CGColorCreateGenericRGB(1.0,1.0,1.0,1.0);
          theObject.color = theColor; // works
          NSLog(@"%@",[theObject valueForKey:@"color"]); // NSValue expected, actually causes exception
          [p release];
          return 0;
      }
      

      一种可能的解决方法是向适当的类添加一个类别,该类为不同的键定义访问器。这些访问器将是 numColour 键的 NSValue 包装器。

      // in the category
      - (NSValue *)numColourKVC {
          return [NSValue valueWithPointer:(void*)self.numColour];
      }
      - (void)setNumColourKVC:(NSValue *)newValue {
          self.numColour = (CGColorRef)[newValue pointerValue];
      }
      

      然后您将在测试平台中设置颜色,如下所示:

      [myCALayerReceiverObject setValue:[NSValue valueWithPointer:(void*)color] forKey:@"numColourKVC"];
      

      【讨论】:

      • 我刚刚注意到,CGColorCreateGenericRGB 不适用于 iOS,所以我的测试代码只适用于 OS X。颜色来自哪里并不重要,因为它不是问题。
      • 感谢您提供这个 ughoavgfhw。自发布问题以来,我一直在与 Opacity 进行沟通,我的代码完全失败的原因归结为创建 CALayer 子类的 Opacity 逻辑中的一个小遗漏。事实上,我最初尝试做的事情是正确的,Opacity 开发人员将在产品的未来版本中解决这个遗漏问题。感谢您的帮助。
      • 但 CGColor 不是标量或结构。它是一个核心基础对象
      【解决方案3】:

      该错误是不言自明的 - 您需要将 CGColorRef 转换为 (id)。在我的脑海中,这应该可以工作:

      [myCALayerReceiverObject setValue: (id)color forKey: @"numColour"];
      

      【讨论】:

      • 说错误是“不言自明”是没有帮助的。真可惜,因为您的回答最终是有帮助且正确的。
      猜你喜欢
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      相关资源
      最近更新 更多