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

Allow NSObject.reactive.signal to also intercept and return the 'return' value of the executed selector. #3557

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

mishagray
Copy link
Contributor

@mishagray mishagray commented Dec 28, 2017

Added the includeReturnValue to reactive.signal(for selector: Selector)

NSObject.reactive.signal(for selector: Selector, includeReturnValue: Bool = false)

Will add a return value to the end of the array, for each value of the Signal.
If the selector does not return a value, than the flag is ignored and no value is appended to the array.

Checklist

  • Updated CHANGELOG.md.

…elector)

NSObject.reactive.signal(for selector: Selector, includeReturnValue: Bool = false)

Will add a return value to the end of the NSArray.
If the method returns Void, than the flag is ignored and no value is appended to the NSArray.
@mishagray mishagray force-pushed the reactive_signal_include_return_vals branch from 03c17dd to f37617d Compare December 28, 2017 19:07
@andersio
Copy link
Member

It looks great with a quick skim. I will take a second look ASAP.

In the meantime, could you please clean up the indentation, the excess blank lines & break the long lines? The GitHub shows quite a few nits.

@andersio andersio self-requested a review December 28, 2017 19:26
/// - returns: A signal that sends an array of bridged arguments.
public func signal(for selector: Selector) -> Signal<[Any?], NoError> {
return base.intercept(selector).map(unpackInvocation)
public func signal(for selector: Selector, includeReturnValue: Bool = false) -> Signal<[Any?], NoError> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is API-compatible but binary-incompatible change. So the original API should be kept as is and the new API should be added as a separete one.

/// - selector: The selector to observe.
/// - includeReturnValue: the array will include the value returned by the invocation. Ignored if the selector returns Void.
/// - returns: A signal that sends an array of bridged arguments.
public func signal(for selector: Selector, includeReturnValue: Bool) -> Signal<[Any?], NoError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to me the wrong way to do this. Instead, it would be better to have a struct that tied together the parameters and return value.

struct Invocation {
    var parameters: [Any?]
    var returnValue: Any?
}


invocation.copyReturnValue(to: buffer)
value = NSValue(bytes: buffer, objCType: retRawEncoding)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's code duplication here between this and the parameters. I think they could be combined so that all this logic doesn't need to be repeated.

case is CInt.Type:
return #selector(InterceptedObject.testReturnValuesI(arg:))
case is CLong.Type:
return #selector(InterceptedObject.testReturnValuesL(arg:))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic unnecessarily complicates the test. It would be better to pass in the Selector directly if possible.

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

Successfully merging this pull request may close these issues.

None yet

4 participants