mutableArrayValueForKey 的 KVC 搜索模式是什么?

发布于 2024-08-21 23:03:14 字数 3196 浏览 7 评论 0原文

我试图更好地理解 Cocoa 的键值编码(KVC)机制。我已阅读 Apple 的 键值编程指南 但我对某些 KVC 方法如何搜索密钥仍然有点困惑。特别是,mutableArrayValueForKey:

下面我将解释我如何理解 valueForKey: KVC“getters” 的工作原理。然后我将回答有关 mutableArrayValueForKey 的问题。


有七种不同的“getter”KVC 方法:

- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;

在属性内搜索值(名为 myKey)时,Apple 文档指出 valueForKey: 搜索如下:

  1. 尝试 -getMyKey-myKey-isMyKey(按该顺序)在接收器内
  2. 如果未找到,它会尝试这些有序的,以-许多吸气剂(NSArray):

    // 必需:
    - (NSUInteger)countOfMyKey;
    
    // 至少需要一个:
    - (id)objectInMyKeyAtIndex:(NSUInteger)索引;
    - (NSArray *)myKeyAtIndexes:(NSIndexSet *)索引;
    
    // 可选(提高性能):
    - (void)getMyKey:(KeyClass **)缓冲区范围:(NSRange)inRange;
    
  3. 接下来,它会尝试这些无序的、一对多的 g​​etter (NSSet):

    - (NSUInteger)countOfMyKey;
    - (NSEnumerator *)enumeratorOfMyKey;
    - (KeyClass *)memberOfMyKey:(KeyClass *)anObject;
    
  4. 接下来,它尝试直接访问实例变量,假设 YES 返回为 YES >accessInstanceVariablesDirectly,按此顺序:_myKey_isMyKeymyKeyisMyKey

  5. 最后,它放弃并调用接收类的 - (id)valueForUndefinedKey:(NSString *)key 方法。通常这里会引发错误。


我的问题是,mutableArrayValueForKey的搜索顺序模式是什么?

Apple 的文档声明了这一点

有序的访问器搜索模式 收藏

默认搜索模式 mutableArrayValueForKey:如下 如下:

搜索接收者的类别 名称匹配的方法对 模式 -insertObject:inAtIndex: 和-removeObjectFromAtIndex: (对应NSMutableArray 原始方法 插入对象:atIndex:和 分别删除ObjectAtIndex:),或 匹配模式的方法 -insert:atIndexes: 和 -removeAtIndexes: (对应于 NSMutableArrayinsertObjects:atIndexes: 和removeObjectsAtIndexes: 方法)。 如果至少一种插入方法和 至少找到一种去除方法 每个 NSMutableArray 消息发送到 集合代理对象将 导致某种组合 -insertObject:inAtIndex:、-removeObjectFromAtIndex:、-insert:atIndexes: 和 -removeAtIndexes:发送到原始接收者的消息 mutableArrayValueForKey:. ...等等...

这对我来说毫无意义,因为它正在讨论“setter”之类的方法。 mutableArrayValueForKey: 返回一个 NSMutableArray。上面列出的所有方法都返回 void,并且用于编辑 NSMutableArray,而不是获取它。示例:

- (void)insertMyKey:(KeyClass *)keyObject inMyKeyAtIndex:(NSUInteger)index;
- (void)removeObjectFromMyKeyAtIndex:(NSUInteger)index;

知道 Apple 在他们的文档中试图说什么,或者这是否可能是一个错误?

我的理论是,在搜索检索 KVC 值时,mutableArrayValueForKey: 可能会采用与 valueForKey: 类似的路径。我只是不确定那到底是什么路。

感谢您提供的任何帮助! :)

I'm attempting to understand Cocoa's Key-Value Coding (KVC) mechanism a little better. I've read Apple's Key-Value Programming Guide but am still a little confused about how certain KVC methods search for keys. Particularly, mutableArrayValueForKey:.

Below I'm going to explain how I understand valueForKey: KVC "getters" to work. Then I'll get to my question regarding mutableArrayValueForKey.


There are seven different "getter" KVC methods:

- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;

When searching for a Value inside a Property (named myKey), Apple's docs state that valueForKey: searches like this:

  1. Tries -getMyKey, -myKey, and -isMyKey (in that order) inside the receiver
  2. If not found, it attempts these ordered, to-many getters (NSArray):

    // Required:
    - (NSUInteger)countOfMyKey;
    
    // Requires At Least One:
    - (id)objectInMyKeyAtIndex:(NSUInteger)index;
    - (NSArray *)myKeyAtIndexes:(NSIndexSet *)indexes;
    
    // Optional (improves performance):
    - (void)getMyKey:(KeyClass **)buffer range:(NSRange)inRange;
    
  3. Next, it attempts these unordered, to-many getters (NSSet):

    - (NSUInteger)countOfMyKey;
    - (NSEnumerator *)enumeratorOfMyKey;
    - (KeyClass *)memberOfMyKey:(KeyClass *)anObject;
    
  4. Next, it attempts to access Instance Variables directly, assuming YES is returned by accessInstanceVariablesDirectly, in this order: _myKey, _isMyKey, myKey, isMyKey.

  5. Lastly, it gives up and calls the receiving class's - (id)valueForUndefinedKey:(NSString *)key method. Usually an error is raised here.


My question is, what is the search order pattern for mutableArrayValueForKey:?

Apple's docs state this:

Accessor Search Pattern for Ordered
Collections

The default search pattern for
mutableArrayValueForKey: is as
follows:

The receiver's class is searched for a
pair of methods whose names match the
patterns -insertObject:inAtIndex:
and -removeObjectFromAtIndex:
(corresponding to the NSMutableArray
primitive methods
insertObject:atIndex: and
removeObjectAtIndex: respectively), or
methods matching the pattern
-insert:atIndexes: and -removeAtIndexes: (corresponding to the
NSMutableArrayinsertObjects:atIndexes:
and removeObjectsAtIndexes: methods).
If at least one insertion method and
at least one removal method are found
each NSMutableArray message sent to
the collection proxy object will
result in some combination of
-insertObject:inAtIndex:, -removeObjectFromAtIndex:, -insert:atIndexes:, and -removeAtIndexes: messages being sent to the original receiver of
mutableArrayValueForKey:.
...etc...

This makes no sense to me as it's discussing "setter" like methods. mutableArrayValueForKey: returns an NSMutableArray. All of the methods listed above return void, and are used to edit an NSMutableArray, not get it. Example:

- (void)insertMyKey:(KeyClass *)keyObject inMyKeyAtIndex:(NSUInteger)index;
- (void)removeObjectFromMyKeyAtIndex:(NSUInteger)index;

Any idea what Apple is trying to say in their docs, or if this is perhaps an error?

My theory is that mutableArrayValueForKey: is likely taking a similar path as valueForKey: when searching to retrieve a KVC value. I'm just not sure what path that really is.

Thanks for any help you can offer! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沙与沫 2024-08-28 23:03:14

从调用 mutableArrayValueForKey: 返回的 NSMutableArray 实际上是 NSMutableArray 的私有子类,它覆盖了普通的数组方法,例如 -count< /code>、-objectAtIndex:-insertObject:atIndex: 等,并在从中检索数组的对象上调用相应的 KVC 方法。它基本上充当操作对象的多对多关系的代理,并且您不必担心自己创建或返回它。一个简单的用法示例:

Playlist* aPlaylist;
Track* aTrack;
NSMutableArray* mutableTracks = [aPlaylist mutableArrayValueForKey:@"tracks"];
[mutableTracks insertObject:aTrack atIndex:0];

这段代码将一个曲目添加到播放列表的开头。如果 Playlist 类为其“曲目”关系实现 KVC 方法,则在可变数组上调用方法将导致在底层对象上调用适当的方法。因此,在此示例中,当您对数组调用 insertObject:atIndex: 时,数组将依次对播放列表对象调用 insertObjectInTracks:atIndex:,并添加曲目到播放列表的曲目数组。

现在,在这个示例中,您当然可以直接调用 insertObjectInTracks:atIndex:,但是使用 mutableArrayValueForKey: 可以带来一些好处。

  • 数组包装器隐藏了底层 KVC 方法的实现细节。实现整个方法列表并不严格要求符合 KVC。 Playlist 类可以只实现 -tracks-setTracks:,上面的代码仍然有效。在这种情况下,可变数组代理将创建一个新数组,并在开头插入对象,而不是调用 insertObjectInTracks:atIndex:,然后只需调用 setTracks:播放列表对象。这显然效率较低,因此通常建议实现 KVC 方法的完整列表。
  • 在这种情况下,您可以使用变量代替键的常量字符串,使用 mutableArrayValueForKey: 允许您操纵关系,而无需知道必须调用的方法的确切名称。只要该对象对于您正在使用的密钥来说符合 KVC,一切都会“正常工作”。
  • 它还允许您使用 NSMutableArray 本身实现的任何方法,例如您可以使用在数组中搜索对象、对数组进行排序等的方法,而无需重写特殊版本来处理 KVC东西。

The NSMutableArray you get back from calling mutableArrayValueForKey: is actually a private subclass of NSMutableArray which overrides normal array methods such as -count, -objectAtIndex:, -insertObject:atIndex:, etc. and calls the corresponding KVC methods on the object the array was retrieved from. It basically acts as a proxy for manipulating the to-many relationship of the object, and it's not something you have to worry about creating or returning yourself. A quick example of usage:

Playlist* aPlaylist;
Track* aTrack;
NSMutableArray* mutableTracks = [aPlaylist mutableArrayValueForKey:@"tracks"];
[mutableTracks insertObject:aTrack atIndex:0];

This piece of code adds a track to the beginning of the playlist. If the Playlist class implements KVC methods for its "tracks" relationship, then calling a method on the mutable array will result in the appropriate method being called on the underlying object. So in this example, when you call insertObject:atIndex: on the array, the array will in turn call insertObjectInTracks:atIndex: on the playlist object, and the track gets added to the playlist's array of tracks.

Now, in this example, of course you could just call insertObjectInTracks:atIndex: directly, but there are several advantages you can get out of using mutableArrayValueForKey: instead.

  • The array wrapper hides the implementation details of the underlying KVC methods. Implementing the entire list of methods isn't strictly required to be KVC compliant. The Playlist class could just implement -tracks and -setTracks:, and the code above will still work. In this case, instead of calling insertObjectInTracks:atIndex:, the mutable array proxy will create a new array with the object inserted at the beginning, and then just call setTracks: on the Playlist object. This is obviously less efficient, so implementing the full list of KVC methods is usually recommended.
  • In the case where, instead of a constant string for the key, you instead have a variable, using mutableArrayValueForKey: allows you to manipulate the relationship without having to know the exact names of the methods you have to call. As long as the object is KVC compliant for the key you're using, everything will "just work".
  • It also lets you use any method that NSMutableArray itself implements, so for example you could use methods that search the array for objects, sort the array, etc. without having to rewrite special versions to deal with the KVC stuff.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文