0

I have a requirement similar to the one described in this question.

I want to dynamically generate getters and setters for a Swift class inheriting from NSObject at runtime (in a similar manner to what NSManagedObject does behind the scenes).

The answers for that question, mentions the usage of @dynamic, to supress Objective-C compiler warnings and then also perform swizzling of methods.

In addition when using CoreData in Swift we have the @NSManaged attribute which tells the Swift compiler that this properties storage is not usual storage but has some custom backing store provided by CoreData.

Is there a way to similarly tell the Swift compiler that my properties for a custom class have custom backing store and not use the usual Swift provided storage?

I am thinking of property wrappers to modify storage, but is it the right direction to go towards or is there some other way?

If we use property wrapper there is one particular feature that I would find unpleasant and want to avoid, when declaring a property using the custom Property wrapper:

@MyCustomPropWrapper(backingStore: someStore) var counter: Int
Rohan Bhale
  • 1,323
  • 1
  • 11
  • 29

1 Answers1

0

You could do something like what you have described using two Objective-C runtime features:

Associated Objects:

You can set a property dynamically on an Objective-C object using associated objects. The documentation for this feature is here, here's a tutorial style guide.

Forward Invocation:

Objective-C uses message style method dispatch. This means that methods are resolved at runtime. Conversely, by default, Swift uses static and vtable dispatch, so all linking is done at compile time. However you can instruct Swift to use messaging by extending from NSObject.

Dynamic dispatch affords the opportunity to provide an implementation of a method that is not statically defined at compile time. The mechanism for this is by using forwardInvocation, which is described here.

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
  • When we declare a swift property as @objc dynamic, method dispatch will be used for accessing that property. But how do I modify the storage mechanism of the properties? – Rohan Bhale Jan 06 '20 at 09:09
  • I dont want them to be stored in backing iVars, I want them to be stored in a dictionary. So when I say @objc dynamic var myInt: Int, I want to control where the Int value will be stored. I am a bit naive here and might lack the required understanding – Rohan Bhale Jan 06 '20 at 09:13
  • You could use forwardInvocation to a method that looks up the property from a single dictionary by key, if you wished. That dictionary object would need to be retained somewhere - not sure of your requirements, but suggest on the object itself. You will have to use ObjC compatible types, ie NSDictionary. – Jasper Blues Jan 06 '20 at 09:24
  • 1
    Ok I will dig deeper in this direction – Rohan Bhale Jan 06 '20 at 09:26