Skip to content
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

-rac_signalForSelector:fromProtocol: #606

Closed
jspahrsummers opened this issue Jun 21, 2013 · 8 comments
Closed

-rac_signalForSelector:fromProtocol: #606

jspahrsummers opened this issue Jun 21, 2013 · 8 comments
Assignees
Milestone

Comments

@jspahrsummers
Copy link
Member

This would add the ability to create signals for undefined selectors that accept non-object arguments (the current limitation of #590), like some delegate methods.

@kastiglione
Copy link
Member

In addition, the simple form of -rac_signalForSelector: could be smarter by, when given an unknown selector, looking for that selector in the protocols adopted by the target instance, instead of naively using all object types.

@jspahrsummers
Copy link
Member Author

I'd rather the behavior be more predictable. If we wanted to get crazy, we could use ext_globalMethodSignatureForSelector, but I'd like to avoid that route if possible.

I think this variant will cover most use cases in a very explicit way.

@kastiglione
Copy link
Member

When a protocol method has non-object arguments, how will NSInvocation instances behave, given:

  1. The caller sets up the registers/stack based on the protocol's argument types.
  2. The system generates an NSInvocation based on the method's declared signature, which is generated as only objects.

I don't know NSInvocation's implementation details, but I suspect dis gon b bad.

@jspahrsummers
Copy link
Member Author

based on the method's declared signature, which is generated as only objects

Not sure what you mean here. NSInvocation can have non-object arguments, and RAC already has categories for reading/writing them as objects.

@kastiglione
Copy link
Member

Not sure what you mean here.

Haha, would you believe I wrote that a couple ways before settling on that? I blame the time of night.

Let's try it this way: Could there be an "ABI mismatch" from what the caller sets up, to what NSInvocation is expecting? If the original protocol signature is a method that takes a single float, but NSInvocation is expecting that the method was called with a single object, NSInvocation won't know to go looking in the applicable float register, right? Or is it super smaht like that?

@kastiglione
Copy link
Member

@jspahrsummers I wrote a test to explore what I described above, and the results were interesting to me. I assumed that the NSInvocation supplied to -forwardInvocation: would be using method signature found on the receiver (the one -rac_signalForSelector: creates), but it's not, it's using the compile time signature that the caller knows.

For illustration, let's say C adopts protocol P, which has declares an optional method -m:(CGFloat)f;, which has a signature of v@:d. However, -m: is not implemented by C.

Next, given an instance of C, and a call to [c rac_signalForSelector:@selector(m:)], c's class will now have a method -m: whose signature is declared as v@:@.

Later, a call to -m:, which will use the compile time signature of v@:d, will be directed to _objc_msgForward which creates an NSInvocation. I assumed this NSInvocation would be using the method signature on the receiver, v@:@, and thus have undefined behavior, but the NSInvocation actually has the original v@:d method signature, so everything works as expected.

@kastiglione
Copy link
Member

In conclusion, the signature we declare matters little, it's the signature the caller uses that matters.

@jspahrsummers
Copy link
Member Author

Yep, exactly. This is why the compiler needs to see a prototype of the method before it can send the message – otherwise, the way it casts objc_msgSend might result in garbage arguments or a garbage return value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants