I find communicating with other script objects somewhat cumbersome. For instance getting properties. An example:
In my document based project I have the AppDelegate do various initial house-keeping and it sets up various folder locations as properties. I have several other script objects and various nib files. How do I access these properties between the objects?
If, e.g, the AppDelegate has set a property aFolderPath, I can’t access it by: current application’s AppDelegate’s aFolderPath()
since that would point to the class AppDelegate rather than its instance, so it fails.
And “current application’s delegate’s aFolderPath()” doesn’t work either (returns the parent class).
And if I create an instance of the AppDelegate in IB via a blue cube and bind it to a property theAppDelegate, and say “theAppDelegate’s aFolderPath()”, it will be for a new instance of AppDelegate, not the existing one, so I would get null as result. So the question is: How do I ask for the properties of the existing App Delegate instance?
A similar problem is accessing a library of methods that must be called as instance methods, such as ObjectWithFords. I can create a new instance of ObjectWithFords in each nib or in each script object instance, but that seems to be a waste. Shouldn’t it be possible to create only one instance of ObjectWithFords and be able to call methods in that one from any other object?
You don’t need to create a blue cube for your app delegate, you get one automatically from the template when you create a project – if you create a property in another script and hook it up to that cube, you should be able to access the app delegates properties.
I’m not at my home computer right now, but I thought that ObjectWithFords was a subclass of NSObject, so you can make your script’s parent ObjectWithFords rather than NSObject, and then call those methods just like any other cocoa method.
current application's NSApp's delegate()'s aFolderPath()
Yes, that’s it! Thanks!
Jeezes, that it should be so difficult to come up with that variation myself… Now that I see it, I understand it, but I just couldn’t come up with it.
From now on I think that will be my standard procedure for creating properties once and then reuse them in other script objects.
As for the following, however:
This way of creating an instance using alloc()'s init() is what I already do in one of the script files (objects) that needs it (done in the init handler). But if I do that in every script object, will there not be a new instance created for each script object? That’s wasting resources by creating multiple instances – one for each script object!? I wanted to access that single instance also from other script objects.
Using your first proposed method to access a property in the delegate might be the solution, i.e create the instance in the AppDelegate and assign it to a property, which then can be read from other objects.That should scale pretty well I guess(?)
What I was describing was not creating the cube in the app delegate, but in another script object that wanted the instance. But as I described, it’s not going to give the desired result since it will create another instance rather than the desired original one.
I am puzzled, however, by your suggestion to hook up that cube in MainMenu nib to a property in a script object that is not the owner (or delegate) of that nib! Is that really doable? How?
I can’t do that since the script objects are subclasses of other things. Besides, I think that’s not a very structured way of dealing with the issue, it doesn’t scale to the general case.
Keep in mind that making separate instances probably isn’t very wasteful of resources. It’s not like the whole thing is duplicated; in simple terms, the instances just store any instance variables plus a pointer to the single class instance. ObjectWithFords has no instance variables. In fact, it could have been written as all class methods; it wasn’t precisely to make it usable as a superclass.
Yes it is doable – you get a blue cube and change its class to your other class (the one that’s not the app delegate). If you create a property in that script, say for example appDel, it should show up if you right click on that class’s blue cube. Just drag from that property to the app delegate’s blue cube and now you can reference the app delegate’s properties (if the app delegate has a property called prop1, you can log it in your other class by writing “log appDel’s prop1” ).
Good to know that new instances aren’t consuming as much resources as I feared, like complete duplicates. Nevertheless, I like the puristic approach of not creating more instances than necessary. It’s hard to know if that’s faster, but I like to think so.
That only works if the blue cube instance of that “other class” already existed there, so it’s the same instance that is executing (i.e the blue cube doesn’t create a new instance). But if I drag a new blue cube to MainMenu nib and set its class to an object that is instantiated elsewhere, or a subclass of NSDocument, and do the connection from the appDel property in that cube to the App Delegate blue cube, it will not work; log appDel’s prop1() would only output the name of the class. This is because it is the wrong instance, the appDel property in the executing instance is never bound to anything, it’s still missing value.
And in the other direction, i.e dragging a blue cube into the nib for that “other class” and set the class of that cube to AppDelegate, it will not work either as I described previously, or to quote myself:
As for the particular case of getting props from the active app delegate, Shane’s suggestion is by far the easiest and fastest: current application’s NSApp’s delegate()'s somePropertyName()
But for getting props from other instances, it can be a bit more involved. But you can get props from a certain document by talking to the document controller thus:
property theDocumentController : missing value --obtained below in a handler
set theDocumentController to current application's NSDocumentController's sharedDocumentController()
set theDocs to theDocumentController's |documents|()
log theDocs's objectAtIndex_(0)'s someProperty()
It probably depends how you access them – there’s some overhead in calling delegate() and then a property accessor, and so on. I understand where you’re coming from, but there’s also an argument for keeping your nibs and classes as self-contained as possible.
Anyway, this is from the docs:
So with classes like ObjectWith Fords, which has no instance variables, you can afford to be profligate