New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix to -rac_signalForSelector: properly implement -respondsToSelector: for optional method from a protocol #926
Fix to -rac_signalForSelector: properly implement -respondsToSelector: for optional method from a protocol #926
Conversation
…he instance has a signal for the selector
id newRespondsToSelector = ^ BOOL (id self, SEL selector) { | ||
SEL aliasSelector = RACAliasForSelector(selector); | ||
BOOL hasSignalForSelector = objc_getAssociatedObject(self, aliasSelector) != nil; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Associated objects are somewhat expensive. We might want to save this check until we've verified that the method exists (below).
This fix makes sense to me. Thanks! ✨ @kastiglione Do you want to take a look too? |
Save accessing a associated object until we've verified that the method exists.
🚀 |
return originalRespondsToSelector(self, respondsToSelectorSEL, selector); | ||
BOOL hasMessageForwardingImplementation = (method != NULL && method_getImplementation(method) == _objc_msgForward); | ||
|
||
if (hasMessageForwardingImplementation || originalRespondsToSelector(self, respondsToSelectorSEL, selector)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the reason for moving the call to originalRespondsToSelector
into this condition? Is there a case where hasMessageForwardingImplementation
is false, yet an associated subject will exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kastiglione Thanks to point out it! It's just my misunderstanding / too much thinking. I made it simple.
@jspahrsummers Just the one question to @ikesyo. Thanks @ikesyo, good fix. |
This reverts commit dcc5107.
Save accessing a associated object until we've verified that the method exists.
@jspahrsummers @kastiglione I made it more cleaner / simpler. Re-ready for review. |
💎💎💎💎💎💎💎💎💎💎🚢💎💎💎💎💎💎💎💎💎 |
Fix to -rac_signalForSelector: properly implement -respondsToSelector: for optional method from a protocol
If an instance is callded
-rac_signalForSelector:fromProtocol:
for a certain protocol's optional method (its class doesn't implement that), the instance should respond to the selector. Then, another instance of the same class that is called-rac_signalForSelector:
with other selectors, but not called with the optional method selector, should not respond to the selector.Originally,
class_addMethod()
makes all instances of the class respondable to the optional method selector. It leads to a crash from-doesNotRecognizeSelector:
at RACSwizzleForwardInvocation in following pattern: