Trying to add an outlet via a CPView category

62 views
Skip to first unread message

Didier Korthoudt

unread,
Apr 21, 2015, 4:30:57 PM4/21/15
to objec...@googlegroups.com
Dear all,

I hope there's a simple, quick, and immediate answer to this (and so, that I'm too tired / dumb / Belgian to find it myself) : for my "auto layout" engine, I need to add methods and properties to CPView. Everything works well. But... (there must be a "but" as I'm writing you) But I also need to add some new outlets to CPView (for example to link a view to a "right neighbour" view). So, in my great excitement, I've just added an :

@outlet CPView _rightNeighbour;

in my CPView category, as I did for other properties.

But, going to IB, no new outlet...

 So, after crying a lot, searching this group, poking around with Google, all I can do now is ask you guys if someone did this kind of stuff and what could be wrong ?

Another "good" answer could be (no, no, don't tell me this) "This is not possible".

Thank you all and good night,


Didier.

Andrew Hankinson

unread,
Apr 21, 2015, 5:06:43 PM4/21/15
to objec...@googlegroups.com
I'm assuming you mean that you need to add a outlet to a subclass of a CPView? Also, why are you adding an outlet to a "private" (underscore) property?

I've often found that if I "Synchronize Project" in XCodeCapp the problems go away. Did you try this?

-Andrew

--
You received this message because you are subscribed to the Google Groups "Cappuccino & Objective-J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to objectivej+...@googlegroups.com.
To post to this group, send email to objec...@googlegroups.com.
Visit this group at http://groups.google.com/group/objectivej.
For more options, visit https://groups.google.com/d/optout.

Didier Korthoudt

unread,
Apr 21, 2015, 5:18:57 PM4/21/15
to objec...@googlegroups.com
Dear Andrew,

Thank you for your answer !

Indeed, between the time I wrote my question and now, I've renamed my property without underscore...

I need to add an outlet to every class beneath (and including) CPView.

I've tried the Synchronize Project but... the only effect what that Xcode flattened my source hierarchy... (no more group of files in Xcode, like "Categories", "DataViews", ...)

Any idea for the initial problem ? Is this possible regarding your own experience ?

Thanks !

Didier.

Andrew Hankinson

unread,
Apr 21, 2015, 6:01:12 PM4/21/15
to objec...@googlegroups.com
Hi Didier,

How are you adding the outlet to CPView? Are you modifying Cappuccino core, or are you using a Category?

Someone else might chime in, but I don't think it's possible to add an outlet in XCode for a core class (e.g., CPView). This is because XCode (and nib2cib) assumes that CPView and NSView are equivalent, so you can't add something to CPView that's not already in NSView. 

If you subclass CPView then you can make the outlets appear in XCode by specifying the subclass name. But AFAIK you can't add outlets to CPView directly.

-Andrew

Didier Korthoudt

unread,
Apr 22, 2015, 12:00:05 AM4/22/15
to objec...@googlegroups.com
Hi again Andrew,

Well, I use a Category as I need to add my "auto layout" capacities to all CPViews and beyond. So a subclass won't do the trick.

Of course, programmatic linking works but it would be smarter to be able to use IB.

Thank you for your time !

Have a nice day,


Didier.

Udo Schneider

unread,
Apr 22, 2015, 12:15:30 AM4/22/15
to objec...@googlegroups.com
Hi Didier,

can't check on live Capp at the moment ... but at least "old-school" ObjC-Runtime does not allow you to add new instance variables to existing classes. Categories only enable you to add methods.

"Categories allow extension of behaviour, not state"
 
as somebody once said.

Current versions of the ObjC-Runtime provide associated objects (http://nshipster.com/associated-objects/). Conceptionally each ObjC-object might have a "dictionary" of associated objects which can be modified. This can be used to implement a kind of ivar storage. This does not (yet) allow you to access the ivar using regular messages (i.e. [object varName]). So you'd still have to add methods for this. And I'm not sure if those methods for associate object accessing are KVO compliant though ...

NSString* myVarKey = @"myVar";


+ (id)myVar
{
   
return objc_getAssociatedObject(self, myVarKey);
}


Now to capp. You can easily add associated objects behaviour with capp. Remember that every Capp Object is a JS Object as well. And a JS Object (from a storage point of view) is just a dictionary. So given any Capp Object "cappObject" you can do something like this:

cappObject._associatedObjects = new Object(); /* Not sure if there is a more intention revealing Dictionary class in JS - but Object does the job */
cappObject
._associatedObjects.key1 = "value1";
cappObject
._associatedObjects["key2"] = "value2";

This will give you the storage part with the usual JS methods. You might want to consider exposing this to capp using the interfaces used for Associated Objects in ObjC :-). E.g. something like (didn't check the code)

/* void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) */
function objj_setAssociatedObject(object, key, value, policy) {
   
if (!object._associatedObjects)
       
object._associatedObjects = new Object();
   
object._associatedObjects[key] = value;
}


This will give you a similar functionality of associated Objects in ObjJ like in ObjC. With the same restrictions in terms of missing methods to access those "ivars".

Now to the real problem: Even if you do get "kind-of-new-ivar" with this method you'll still be stuck on outlets. For IB to pickup outlets for your classes you it has to be in the .h file with an IBOutlet "macro". And this will only be generated by xCodeCapp for your custom classes when the @outlet annotation is found. But if it's your class you don't need that way of associated objects based ivars anyway because you can add regular ivars. And for base classes the defined outlets are hardwired into IB (coming from NSView as Andrew pointed out) anyway. So you're out of luck here.

So I'd say you have to setup outlets and action/target for those kind of ivars in code. awakeFromCib might be a good place for that.

CU,

Udo

Martin Carlberg

unread,
Apr 22, 2015, 1:12:17 AM4/22/15
to objec...@googlegroups.com
Hi,

You are correct that you can’t add an ivar in a category in Objective-C. But you can add a ’new school’ property.

@interface NSView (MyOutlet)

@property IBOutlet id myOutlet;

@end

This property will show up in the Interface Builder on all objects that inherits from NSView. Works like a charm.

Objective-J does not have properties but it allows you to add ivars in categories. I.e. you can to do the same thing in Objective-J as in Objective-C by creating an ivar instead of a property.

A problem is that XCodeCapp does not generate a correct .h file for the Interface Builder to read. You will never see the outlet in the Interface Builder. This is a bug in XCodeCapp.

You might be able to create a .h file manually that adds your outlet and makes the Interface Builder happy.


Happy coding,

- Martin


Udo Schneider

unread,
Apr 22, 2015, 3:18:41 AM4/22/15
to objec...@googlegroups.com
Hi,

Objective-J does not have properties but it allows you to add ivars in categories. I.e. you can to do the same thing in Objective-J as in Objective-C by creating an ivar instead of a property.
Good to know. So in this regard the ObjR-Runtime is even more flexible than the ObjC-Runtime. Nice. 

A problem is that XCodeCapp does not generate a correct .h file for the Interface Builder to read. You will never see the outlet in the Interface Builder. This is a bug in XCodeCapp.
Is there maybe a "post-convert" hook in XCodeCapp which would allow calling a script or something like that? This way one could at least add the missing stuff semi-manually until this bug is fixed.

CU,

Udo

Martin Carlberg

unread,
Apr 22, 2015, 3:36:38 AM4/22/15
to objec...@googlegroups.com

22 apr 2015 kl. 09:18 skrev Udo Schneider <udo.sc...@homeaddress.de>:

Is there maybe a "post-convert" hook in XCodeCapp which would allow calling a script or something like that? This way one could at least add the missing stuff semi-manually until this bug is fixed.

I don’t think there is a hook but maybe someone else can answer that. You could try to just add the .h file manually.

- Martin

Didier Korthoudt

unread,
Apr 22, 2015, 4:29:06 AM4/22/15
to objec...@googlegroups.com
Thank you all for your messages !

I've digged in xCodeSupport files and found the header generated by xcc :

#import <Cocoa/Cocoa.h>

#import "xcc_general_include.h"


@interface CPView (AutoLayout)


@property (assign) IBOutlet NSView* topNeighbour;


@end


So, Martin you were right.

But it doesn't work.

If somebody has an idea, I'll take it and meanwhile I'll try to digg further...

Have a nice day !


Didier.

Martin Carlberg

unread,
Apr 22, 2015, 5:23:34 AM4/22/15
to objec...@googlegroups.com
Try to write "@interface NSView (AutoLayout)” instead of "@interface CPView (AutoLayout)".

Martin

Didier Korthoudt

unread,
Apr 22, 2015, 10:22:17 AM4/22/15
to objec...@googlegroups.com


Le mercredi 22 avril 2015 11:23:34 UTC+2, mrcarlberg a écrit :
Try to write "@interface NSView (AutoLayout)” instead of "@interface CPView (AutoLayout)".

Martin



Great ! This works !

So this is related to XcodeCapp...

Thank you Martin !

Didier. 

Dogild

unread,
Apr 22, 2015, 12:57:10 PM4/22/15
to objec...@googlegroups.com
Yop,

Yep it's not really a bug, xCodeCapp did not have this feature yet (you an open an issue on github for this one). When xCodeCapp was developed, it was not possible to add ivars in a category, this is why it does not work

Didier Korthoudt

unread,
Apr 22, 2015, 2:01:40 PM4/22/15
to objec...@googlegroups.com
Of course this is not a bug but a missing feature ! I wrote "related to xCodeCapp"...

;-)

I'll open a feature request for this...

Thank you all !

Best Regards and have a good night !


Didier.

Dogild

unread,
Jun 1, 2015, 9:27:24 PM6/1/15
to objec...@googlegroups.com
This has been fixed in the master !

Didier Korthoudt

unread,
Jun 2, 2015, 1:52:36 PM6/2/15
to objec...@googlegroups.com
Great ! Thank you !
Reply all
Reply to author
Forward
0 new messages