ios-jsc icon indicating copy to clipboard operation
ios-jsc copied to clipboard

Objective-C Inheritance using ES6 Class syntax

Open PanayotCankov opened this issue 10 years ago • 8 comments

Once we have adopted the latest JSC version, we can implement the Objective-C inheritance using the class syntax.

PanayotCankov avatar Jun 02 '15 13:06 PanayotCankov

Will this fix the problem of passing an object with inherited properties to extend? I'm currently getting «No implementation found for exposed method...» for functions that are inherited from another object. E.g. with UIViewController.extend(Object.create(SharedFunctions)).

moll avatar Aug 06 '15 22:08 moll

@moll: if you use some sort of mixin mechanism that copies the shared functions to each JavaScript class before registering it in the Objective-C runtime, then yes.

fealebenpae avatar Aug 07 '15 10:08 fealebenpae

Umm, what do you mean by mixin mechanism? I've just got Object.create in mind to take advantage of prototypes in a prototypical language. :)

moll avatar Aug 07 '15 10:08 moll

Right now the object you pass to NSObject.extend becomes the prototype of the new class - its __proto__ is set to the prototype of the class you extend (in your case UIViewController). This means that any connections to an existing prototype chains are severed. What's more, the current extend mechanism only considers the object's own properties, largely because for the purposes of extend it never exists in a prototype chain other than the one extend itself builds.

What you can do right now is manually copy the functions in SharedFunctions to the object you pass to extend and this should have the desired effect. With classes, however, you would be able to use a mixin mechamism to achieve the same result in a more idiomatic way.

fealebenpae avatar Aug 07 '15 10:08 fealebenpae

Ah, thx, mkay, then it makes sense inherited properties won't work now.

I take it the proposal in this issue will split the inheritance and method-exposing and class registering bits, right? Cause creating an object that has UIControllerView as an ancestor prototype is a different concern from making its public methods available for iOS. Then I could use whatever inheritance scheme I'm after as long as the root of it inherits from e.g. UIControllerView. That would have to happen with the class syntax anyways I assume.

PS. Opened an issue on the extend plugin you linked to. Turned out it's consistent with its inherited properties use too. Other than that a simple for in loop would do the trick equivalently.

moll avatar Aug 07 '15 11:08 moll

Yes, you are correct, the idea is to create a new register function that accepts a constructor function with prototypes and everything already attached like so:

class MyView extends UIView {
    constructor(value) {
        super();
        this._value = value;
    }

    drawRect(rect) {
        // drawing logic here
    }
}
interop.objc.register(MyView);

You could do the same by wiring everything by hand like so:

function MyView(value) {
    var self = Reflect.construct(UIView, undefined, MyView);

    self._value = value;
    return self;
}
Object.setPrototypeOf(MyView, UIView);
MyView.prototype = Object.create(UIView.prototype);
MyView.prototype.constructor = MyView;
MyView.prototype.drawRect = function () {
  // drawing logic here  
};
interop.objc.register(MyView);

In this case however you need to ignore the this value JavaScript generates for you when evaluating new MyView('foo') and invoke the base constructor. That is because the JavaScript constructors for Objective-C classes return a special kind of object that is bound to a native Objective-C object and manages its lifetime. The new class syntax invokes the base constructor and uses it to initialize the this value inside the constructor function when you execute super() instead of you having to do it by hand.

fealebenpae avatar Aug 07 '15 12:08 fealebenpae

ES6 class syntax is sadly being postponed for 1.4.

fealebenpae avatar Aug 20 '15 14:08 fealebenpae

  • 💯 We need to support this in order to switch TypeScript to ES2015 output.

hshristov avatar Aug 10 '16 07:08 hshristov