-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Changes to the DynamicProperty
semantics.
#3162
Conversation
👎 I don't think this is the way to go. A
Now, //these// semantics I think are correct. But the previous point kind of breaks this because there would be one extra artificial owner. |
@@ -5,71 +5,70 @@ import enum Result.NoError | |||
/// types, including generic types when boxed via `AnyObject`). | |||
private protocol ObjectiveCRepresentable { | |||
associatedtype Value | |||
static func extract(from representation: Any) -> Value | |||
static func represent(_ value: Value) -> Any | |||
static func extract(from representation: Any?) -> Value |
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.
Why Optional
? representation
can always be an optional (since it's Any
).
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.
If you pass an optional to Any
, it would be bridged to an opaque box (SwiftValue
) regardless of being nil
or not. The KVC interface in fact anticipates Any?
.
The way DynamicProperty
is initialised also restricted the implementation options. Since optionals are neither bridgeable nor conforming to AnyObject
, new initializers have to be tailored for optionals with the OptionalProtocol
constraints. Unless we assume all key paths are nullable & requires manual nil
skipping.
It might be confusing since It creates a reduced view (lens) to the NSObject, which concerns only a certain key path. In this sense, you are still accessing the object directly, i.e. conceptually the same as However, all other stuff (producer/signal/lifetime/binding) is decoupled and instead derived directly from the underlying object. This aligns with our property composition and signal lifetime semantics. For example, if you retain Now treat It also eliminates potential leaks due to misuse, since at this moment every instance of This is actually similar to Groff's idea of "property lenses" for property reflection, say a |
I agree with @NachoSoto on this. I think the I definitely get what you're saying about the lens behavior. But if we want to support those semantics, they need to be in addition to the current semantics—not as a replacement. |
# Conflicts: # ReactiveCocoaTests/Swift/PropertySpec.swift
004d3df
to
00de2e0
Compare
I don't think we should give Going back to your original example: DynamicProperty<Int>(object: controller,
keyPath: #keyPath(Controller.value)) <~ aProducer I don't think that provides much value. If the |
Yeah, and that lens-ish part has been removed. What's left here is the removal of the strong reference, so that |
Yeah, and I just don't think those are the right semantics for |
I don't think the semantics have changed per the state of PR, other than lifting the need of uniquing. If we agree that the main rationale of If the need of uniquing is a deliberate feature, I would argue that the initializer should hide behind something that does the uniquing, instead of the slippery ground we have now. |
Make it more
Property
alike - a lens to a key path of anNSObject
without its own lifetime.ADynamicProperty
retains its lensing object.The producer and signal respects the lifetime of the object being lensed.
Bindings targeting
DynamicProperty
ties directly to the object being lensed.DynamicProperty
is now leak safe - reusing instances is no longer necessary.For example:
would still be valid even if the
DynamicProperty
has gone out of scope. It would last untilcontroller
deinitializes, oraProducer
terminates.