2

我想获得一个指向存储在 an 中的对象的指针,NSValue以便我可以修改它。要点是这样的:

// Get a pointer to the value's buffer (it'd be void*, I guess).
CGRect *myRect = [rectValue getPointer];

// Modify the rectangle.
myRect->origin = CGPointMake(10, 10);

我注意到NSValue有方法pointerValue,但文档说:

该值作为指向 void 的指针。如果未创建值对象来保存指针大小的数据项,则结果未定义。

…所以这似乎只适用于指针值,这不是,它是一个CGRect.

顺便说一句,如果答案是“你不能这样做”,就我而言,这仍然是一个很好的答案 :-) 解释为什么不这样做会很有趣,因为它似乎在 API 中明显缺失.

4

1 回答 1

1

我相信答案确实是,“你不能这样做。”*

以下是一些关于为什么会出现这种情况的原因。

  • NSValue像 Objective-C 中的许多核心数据类型一样,是不可变的。允许您获取指向存储在实例中的内部值的指针对于它的不变性来说并不是很好。
  • 访问这样的指针将不可避免地返回一个void *. 这绕过了编译器的所有类型检查能力,这是为了您自己的利益!
  • 一般而言,类会尽量将它们的内部状态和功能隐藏在外部世界之外,并仔细管理与外部世界的交互。想象一个实例的愚蠢情况,NSValue每次您将其存储值作为 a 访问时CGRect都想知道(据我所知,NSValue实际上并没有监视它)。使用指针,它无法知道您何时这样做。但是,使用方法-[NSValue CGRectValue],您别无选择,只能通知它。

尤其是面对前两个原因,您甚至可能会对自己说,如果这一切都是真的,为什么pointerValue存在?这确实可能允许可变性,并且确实可能​​允许不对指针进行类型检查。好问题,但很容易回答:如果您NSValue使用指针创建一个实例 - 比如说,使用+[NSValue valueWithPointer:],从实例中取回该指针的唯一选择是返回 的方法void *。其他任何事情都将构成该方法的某种假设

* “不能”在这里是一个相对术语。例如,valueForKey:如果您知道内部密钥名称,它可能仍然有效。

于 2014-12-05T22:02:58.290 回答