Menu

#74 Add an option to use a @protocol in Objective-C

None
closed
None
3
2021-01-01
2010-08-30
Dave Dribin
No

The "owner" class in Objective-C is a full class. In many cases, I would prefer if it were a protocol (which is similar to a Java interface). This would make it easier to unit test the generated state machine, for one.

The main change is how the Objective-C code is generated. Instead of print the "context" class as

AppClass * _owner;

It needs to be:

id<AppClass> _owner;

I'm attaching a patch that adds a "-protocol" command line option for use with -objc that implements this feature.

Related

Discussion: Any feedback on feature request #74? Thinking of updating the patch for current code

Discussion

  • Dave Dribin

    Dave Dribin - 2010-08-30

    Patch file that implements this feature.

     
  • Mark Aufflick

    Mark Aufflick - 2015-06-22

    ++ for this change - is there anything I can do to help it along? I'm guessing that the patch is out of date by now, but since it wasn't applied at the time I'm wondering if there were any philosophical objections etc. before I put any time into it?

     
  • Mark Aufflick

    Mark Aufflick - 2015-06-22

    The more I think about this, the better it seems. Defining it as a protocol would also formalise in the headers what methods the owner needs to exist, and the compiler/editor will warn (in the right place) any owner methods that have not yet been implemented.

     
  • Charles Rapp

    Charles Rapp - 2015-07-23
    • assigned_to: Charles Rapp
    • Group: -->
     
  • Charles Rapp

    Charles Rapp - 2015-07-23

    I was slow in taking up this feature because I know nothing about Objective-C and am entirely dependent on others for help on -objc. Looking at your patch, I see you are slightly behind on releases. It was impressed upon me that the context class should have a __weak reference to its owner. This change was due to Apple's ARC feature.

    I assume that the "__weak" keyword should emitted even if the -protocol option is used. Is this correct? Do you even use ARC?

     
  • Mark Aufflick

    Mark Aufflick - 2015-07-23

    Hi Charles,

    Yes, well before ARC you just would use a non-retained attribute but then you have to be careful not to use a released pointer, the beauty of __weak is that the pointer is zeroed as soon as the referenced object is released so you avoid the retain/reference cycle while avoiding the risks of inadvertently using a freed pointer.

    Changing to a protocol instead of a class doesn't change this at all - the user is still going to implement basically the same object as before, it's just that instead of implementing the class defined by the generated code, the user is free to implement a base object, or inherit from whatever they want, so long as it complies with the protocol. It will be passed in as owner just as before.

    I've been playing with this a bit and I can't really alter the generation code to do what I want. Ideally the protocol definition itself would be generated, but this isn't possible at the moment. The protocol needs to define the methods for both the actions and the transition guards, but since the .sm format allows arbitrary language-specific code in the transition guards that's not possible since you can call methods on context.owner (which I often do - not sure if that is idiomatic, but it prevents putting large amounts of duplicated logic in the guards). Not only would I have to parse that code, I wouldn't have the type information.

    The patch as created by Dave Dribin requires the user to write the protocol header themselves which eliminates part of the benefits, but is still useful for two reasons - the testing example Dave gives, but it should (haven't tried yet) allow us to use Swift objects as the context which are pure Swift objects that adopt the ObjC protocol which is a lot easier way to get better Swift integration without writing an actual Swift runtime and generator.

    Sorry for the long message, thought I'd give you all my thinking so far! BTW I've mirrored the svn into a git repo (manually kept in sync with git-svn so it keeps all the history) and then applied Dave's patch to a fork of that.

    Mirror: https://github.com/aufflick/smc_mirror

    Fork: https://github.com/thehtb/smc

    I'm half heartedly thinking of forking the .sm format to make guard conditions a specific meta format like actions, but then whether I would fork the java code or make my own compiler and use these runtimes is an open question. The reality is of course I will probably never do either ;)

     
  • Mark Aufflick

    Mark Aufflick - 2015-07-25

    Of course another simpler solution is to allow % header lines to insert methods into the protocol header where methods are needed for transition guards. It's not a great approach, but compared to wholesale change it mightn't be a bad compromise.

     
  • Charles Rapp

    Charles Rapp - 2015-08-02

    I will include the original -protocol option in the next release (SMC 6.6.0) but leave it undocumented. You can use it if you and I will keep it around until a better solution is found.

     
  • Charles Rapp

    Charles Rapp - 2015-08-02
    • Priority: 5 --> 3
     
  • Charles Rapp

    Charles Rapp - 2015-08-02

    Feature in release 6.6.0.

     
  • Charles Rapp

    Charles Rapp - 2015-08-02
    • status: open --> accepted
     
  • Mark Aufflick

    Mark Aufflick - 2015-08-03

    Awesome thanks - I'll start using it as is which should help me flesh out the best approach.

     
  • Dave Dribin

    Dave Dribin - 2015-08-16

    Excellent! Though, I don't really know why it should be hidden. There is no "better" solution. In fact, a protocol should really be the default. There's no benefit to using a class.

    ARC and "weak" is completey separate from a using protocol. Even a class should be "weak" to avoid a retain cycle.

     
  • Charles Rapp

    Charles Rapp - 2021-01-01
    • status: accepted --> closed
     
  • Charles Rapp

    Charles Rapp - 2021-01-01

    Closed as implemented in SMC release 6.6.0.

     

Log in to post a comment.