allending/Kiwi — pull request #512 by sharplet (2014-05-03 09:13:14+00:00)
Title: Fix #509

The infinite loop was caused when a stubbed object references a stub from within its implementation of `-hash`:

1. We create the stub, which has the side effect of adding the receiver to a global map table,
2. which causes `-hash` to be sent to the object,
3. which calls the stubbed method,
4. which causes the object to be added to the global map table,
5. goto 2.

In this patchset, we break this cycle by using a different object as a key in the `KWObjectStubs` map:

1. Create a block which returns a weak reference to the stubbed object
2. Associate the block with the object using `objc_setAssociatedObject`, so that we can get a reference to it later
3. Use the block as the key in `KWObjectStubs`

Using a block means that when we enumerate the all the keys in `KWObjectStubs` (i.e., when clearing all stubs), we can get a reference to the original object by invoking the block.

Not sure if this is the best approach (particularly the associated objects bit), but it works pretty well. Feedback welcome on the implementation!