Inherits From: NSObject
Conforms To: NSObject (NSObject)
Declared In: Foundation/NSByteStore.h
An NSBTreeCursor provides access to the keys and values stored in an NSBTreeBlock. It's essentially a pointer into the NSBTreeBlock's key space, and may be positioned by key to perform operations on the value stored at a given location.
An NSBTreeCursor works with a single NSBTreeBlock, but several NSBTreeCursors may access the same NSBTreeBlock and be positioned independently without conflict. See the NSBTreeBlock class specification for more information on concurrent access with multiple NSBTreeCursors.
Positioning the Cursor and Accessing Data
NSBTreeCursor contains methods that walk through the key/value pairs in the NSBTreeBlock. The method moveCursorToFirstKey will point the cursor to the first key in the key space, and you can use moveCursorToNextKey to essentially walk through all of the keys in the NSBTreeBlock. To point the cursor at a specific key/value pair, use moveCursorToKey:. This method returns YES if it finds the key and NO if it does not. If moveCursorToKey: returns NO, it still points the cursor at that key. For example, suppose the keys into the key space are integer IDs divisible by 10, and you call moveCursorToKey: with 54 as the key. (In reality, keys must be NSData objects, but to make this example more clear, it uses integers.) There is no key 54, so moveCursorToKey: returns NO, but the cursor points to where key 54 would be if it existed. A subsequent call to moveCursorToNextKey would point the cursor at key 60. The method isOnKey tells you if the cursor is pointing to a valid key.
To insert a key/value pair into the NSBTreeBlock, you take advantage of the moveCursorToKey: method's return value. Send moveCursorToKey: with the key you want to insert. If if returns NO, send writeValue: with the value you want to insert. The key/value pair will be inserted.
A cursor at a position with no key can't access a value there. If the cursor is asked to access a value anyway, it has two options: try to find a value or indicate that it can't access one. Where it makes sense, a cursor should try to find a value by sliding forward in the key space to the next actual key. When this isn't possible or desirable, the cursor should indicate that it can't find or access a value, by raising the NSBTreeNoValueException exception. In the previous example, if the cursor is asked to retrieve the information at key 54, the cursor will slide forward and return the information at key 60. At this point, you can use the cursorKey method to find out which key the cursor is pointing to. cursorKey will return 60 to let you know that the cursor has slid forward.
A cursor cannot write inside (with the method writeValue:range:) or remove the value (with the method removeValue) at a location where there is no key. Since there is no value, and since writing into part of a value or removing it would change data that the programmer probably doesn't want altered (namely, the value for the next actual key), the NSBTreeCursor will indicate that there is no value to write into by raising the NSBTreeNoValueException exception.
Working With the NSByteStore
Since NSBTreeBlock is an NSByteStore client, the transaction model of NSByteStore applies to changes made to the contents of an NSBTreeBlock. In particular, you must send the commitTransaction message to the NSByteStore to have changes to the NSBTreeBlock take effect (and be flushed to disk for a file-based store). If an NSBTreeBlock is used on a strictly read-only basis, transaction management can be ignored.
After an abortTransaction, a cursor may be pointing to a key that no longer exists. Therefore, you must reposition each cursor using one of the moveCursor... methods after an abortTransaction.
Creating and Initializing a New NSBTreeCursor Instance