My colleague and I are building an async data layer heavily based on PromiseKit v1.5.3. We've noticed in certain circumstances, when returning a promise (call it X) from a block passed to then
, the next then
block actually passes Promse X as the argument to the block, rather than what the former promise actually resolved to. Chaining thenable promises is a pretty important feature for most Promise implementations, so we were pretty surprised.
After some pretty lengthy debug sessions, we've found the problem to be within PromiseKit. During the resolution process, an IsPromise
call fails to identify the object as a promise, which is really a simple call to
[result isKindOfClass:[PMKPromise class]]
This call returns nil
, and an incorrect branch is executed. Here's the source
The baffling thing about this, is that I don't see any reason for this to happen. I don't think this is a bug in PromiseKit since their code appears to be sound. I've confirmed the underlying object is indeed a PMKPromise since it responds to promise methods such as value
and fulfilled
. I've even pushed it through the correct branch using the debugger and it executes correctly from there!
Here's an interesting log from some tests while halted at the given line.
Given that isKindOfClass
is returning nil
, it sounds like that object isn't responding to the message... but it's certainly an NSObject. I'm curious if this may be a weird compiler setting or something. I currently have my optimizations set to none if that's relevant. Has anyone ever seen anything like this or know what's going on? What should I check?
isKindOfClass returns unexpected results when you manage to have the same class twice in your project. So you may have an object of class PMKPromise, but it is a different class (with exactly the same class name, exactly the same behaviour, just a second class). Maybe that's what happens. Obviously setting a breakpoint and checking what the object is would help.