How to implement the NSFastEnumeration protocol?

此生再无相见时 提交于 2019-12-29 03:27:06

问题


I have a class and I want my class to confirm to the NSFastEnumeration Protocol. I've read the documentation but it's not really clear. Can someone please tell me what the protocol method should return and how it works?


回答1:


Apple's FastEnumerationSample shows you what to do, but here's a breakdown.

The sole NSFastEnumeration method, countByEnumeratingWithState:objects:count:, returns chunks of the collection. It's executed whenever more items are needed, until it indicates that there are no more items by returning 0. A chunk is passed as a C array of ids.

Within the method, the state parameter holds most (if not all) of the data you'll be using. You'll need to set state->itemsPtr and update state->state with each separate invocation of countByEnumeratingWithState:objects:count:. Here's a brief description of each field of NSFastEnumerationState:

  • state: represents the position in the sequence being iterated over. For indexed collections, this would be the index. For linked lists, this could be a node pointer. For other types, this could be a more complex type (e.g. for a tree, state->state could be an NSMutableArray used as a stack to store nodes). When countByEnumeratingWithState:objects:count: is first called, state->state is 0; check for this condition to initialize the state struct.
  • itemsPtr: the items in the chunk; points to a C array of ids. Cocoa will loop over this array, binding each item in turn to the variable named in the for-in loop.
  • mutationsPtr: for mutable collections, used to indicate that the collection has changed since the last call to countByEnumeratingWithState:objects:count:. Typically, you'd set this once when initializing the state. Collection mutators increment the value that this points to. Cocoa will compare the value returned by countByEnumeratingWithState:objects:count: to the value from the previous invocation; if they're different, Cocoa will throw an exception.
  • extra: you can use this to store extra data.

You can set state->state and any element of state->extra to whatever you wish; they're provided solely for your convenience, and do not affect Cocoa. state->itemsPtr, *state->mutationsPtr and the value returned by the method, however, do affect Cocoa.

As for the two other method parameters, stackbuf is an array that Cocoa provides to hold items. Its use is optional, but if you don't use it, you'll have to allocate storage space for state->itemPtr. If you use it, set state->itemsPtr to stackbuf with each invocation. len is the length of stackbuf, the maximum number of items that you'll be able to store in it.

Further reading:

  • Friday Q&A 2010-04-16: Implementing Fast Enumeration (mikeash.com)
  • Implementing countByEnumeratingWithState:objects:count: (Cocoa with Love)
  • NSFastEnumeration Protocol Reference
  • Implementing NSFastEnumerator on Custom Class (SO)



回答2:


Just reviving this thread after finding an excellent explanation. The Apple link seems to be broken. You can try here: https://developer.apple.com/library/ios/#samplecode/FastEnumerationSample/Introduction/Intro.html

The best example for implementing fast enumeration that I've found is at: http://mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.html. It looks much worse than it is.



来源:https://stackoverflow.com/questions/4872509/how-to-implement-the-nsfastenumeration-protocol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!