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

Improve key implementation #28

Merged
merged 13 commits into from
Jan 26, 2024
Merged

Improve key implementation #28

merged 13 commits into from
Jan 26, 2024

Conversation

p-x9
Copy link
Owner

@p-x9 p-x9 commented Jan 19, 2024

Within a Protocol Extension, stored property could not be defined, and an error occurred in the definition of the AssociatedObject's Key.

Therefore, I modified the implementation of Key to use Selector.

related to: #24

@mlch911
Copy link
Contributor

mlch911 commented Jan 20, 2024

We can add a assert in the setter to check is there anything wrong.

var string: String? {
    get {
        objc_getAssociatedObject(
            self,
            Self.__associated_stringKey
        ) as? String?
        ?? nil
    }
    set {
        objc_setAssociatedObject(
            self,
            Self.__associated_stringKey,
            newValue,
            .OBJC_ASSOCIATION_ASSIGN
        )
        assert(string == newValue)    // <-- Add this.
    }
}

static var __associated_stringKey: UnsafeRawPointer {
    unsafeBitCast(
        NSSelectorFromString("__macro_local_6stringfMu_"),
        to: UnsafeRawPointer.self
    )
}

@p-x9
Copy link
Owner Author

p-x9 commented Jan 20, 2024

@mlch911

I think it is a good idea.
However, I think it would be difficult to check that the type is Equatable using only syntax.

@mlch911
Copy link
Contributor

mlch911 commented Jan 20, 2024

Maybe this.

set {
        objc_setAssociatedObject(
            self,
            Self.__associated_stringKey,
            newValue,
            .OBJC_ASSOCIATION_ASSIGN
        )
    if type.of(string).confirm(to: Equitable.self) {
        assert(string == newValue)
    }
}

@p-x9
Copy link
Owner Author

p-x9 commented Jan 21, 2024

@mlch911 This function may exist only in NSObject.

@p-x9
Copy link
Owner Author

p-x9 commented Jan 23, 2024

I have made some changes to the way keys are generated in order to support future platforms, such as Linux, where the Objective-C runtime is not available.

Instead of using Selector, function pointers are used as keys.

static var __associated_boolKey: UnsafeRawPointer {
    let f: @convention(c) () -> Void = {}
    return unsafeBitCast(f, to: UnsafeRawPointer.self)
}

@mlch911
Copy link
Contributor

mlch911 commented Jan 23, 2024

I have made some changes to the way keys are generated in order to support future platforms, such as Linux, where the Objective-C runtime is not available.

Instead of using Selector, function pointers are used as keys.

static var __associated_boolKey: UnsafeRawPointer {
    let f: @convention(c) () -> Void = {}
    return unsafeBitCast(f, to: UnsafeRawPointer.self)
}

Would this return the same pointer every time? Shouldn't this be like this?

static let __associated_boolKey: UnsafeRawPointer = {
    let f: @convention(c) () -> Void = {}
    return unsafeBitCast(f, to: UnsafeRawPointer.self)
}()

@p-x9
Copy link
Owner Author

p-x9 commented Jan 23, 2024

Closure functions are not defined dynamically, but statically, just like any other function definition.
Therefore, it should return the same pointer value change each time.

And for cases where it is not possible to define a property of a stored type, such as a protocol extension, I want to define it as a calculated type property as much as possible.

@p-x9 p-x9 merged commit f1fb296 into main Jan 26, 2024
1 check passed
@p-x9 p-x9 deleted the feature/improve-key-implementation branch January 26, 2024 12:07
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.

2 participants