Snowman
Snowman

Reputation: 32091

Why does the following code result in infinite recursion?

class TestClass : NSObject {

    var definitions: NSSet = NSSet()

    func addDefinitionsObject(value: AnyObject) {
        self.mutableSetValueForKey("definitions").addObject(value)
    }

    func removeDefinitionsObject(value: AnyObject) {
        // this method is never called
        self.mutableSetValueForKey("definitions").removeObject(value)
    }
}

var test = TestClass()
test.addDefinitionsObject("yo")

Running this causes infinite recursion, which ultimately crashes with EXC_BAD_ACCESS. Any ideas why this is happening?

What's weird is that this only happens if removeDefinitionsObject is defined. If I remove that function, the issue goes away.

Upvotes: 3

Views: 261

Answers (1)

Martin R
Martin R

Reputation: 540055

From "Accessor Search Pattern for Unordered Collections" in the "Key-Value Coding Programming Guide" (emphasis mine):

The default search pattern for mutableSetValueForKey: is as follows:

  • Searches the receiver's class for methods whose names match the patterns add<Key>Object: and remove<Key>Object: (corresponding to the NSMutableSet primitive methods addObject: and removeObject: respectively) and also add<Key>: and remove<Key>: (corresponding to NSMutableSet methods unionSet: and minusSet:). If at least one addition method and at least one removal method are found each NSMutableSet message sent to the collection proxy object will result in some combination of add<Key>Object:, remove<Key>Object:, add<Key>:, and remove<Key>: messages being sent to the original receiver of mutableSetValueForKey:.
  • ...

Which means that if both addDefinitionsObject and removeDefinitionsObject are implemented in your class, then

self.mutableSetValueForKey("definitions").addObject(value)

calls

self.addDefinitionsObject(value)

hence the recursion.

Upvotes: 2

Related Questions