Adding applescript class file to Cocoa project

Got it! Don’t know why it didn’t work the first few times around. does now.

Yes Garbage collection was off. I am learning obj-c and memory management, finally gaining a foothold there. I suppose it is mandatory to turn GC on if using ASOC applescript classes?

Thanks Shane.

Rob

No – but you’ll have to include all the retain()s and release()s if you don’t.

Hi Shane,

That’s what I thought, but just including the script without calling any methods seems to trigger the warning. I commented out the code and still get “autoreleased with no pool in place - just leaking.” What is getting autoreleased?

script ASClass
	property parent : class "NSObject"
	
	(*on callDialog_(sender)
		display dialog "Hello world"
	end callDialog_
	
	on displayDialog()
		display dialog "Hello world"
	end displayDialog*)
	
end script

Rob

I don’t know, and I don’t know that I want to know :slight_smile:

Could it be the “[[NSBundle mainBundle] loadAppleScriptObjectiveCScripts]” in main.m?

I do and I don’t.

Cheers, Rob

Indeed, in a non-GC environment every Cocoa call in main.m must be wrapped with an autorelease pool

[code]#import <Cocoa/Cocoa.h>
#import <AppleScriptObjC/AppleScriptObjC.h>

int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSBundle mainBundle] loadAppleScriptObjectiveCScripts];
[pool release];
return NSApplicationMain(argc, (const char **) argv);
}[/code]

Is your test using both an ObjCClass.h and ObjCClass.m ??? That’s what I had set up:

Well, I got mine to work finally, but I had to make a change to…

Which I thought looked funny at first, and seemed to react the wrong way (from what I expected) in IB.

From a bit of experience in pure ASOC, this is telling me that any messages I want to send to an instance of ASClass are actually going to be sent to SomeAppAppDelegate, since “myASClass” is tied to it with “IBOutlet SomeAppAppDelegate *myASClass;”. Thus the error messages I was getting:

I looked your code over and over and over and thought it seemed wrong, but you had indicated that it works, so I figured I was just not understanding some message passing voodoo when working in real ObjC.

So when I see:

This tells me that I’m wanting to invoke the “myTest” method on SomeAppAppDelegate. That seems to match error in the log. So I changed the IBOutlet and fixed broken connections in IB:

Now I’m getting my messages (method calls) properly in ASClass. Whew. As I expand on that and run more tests I find something interesting. I get warning messages on 3 of these 4 methods:

I understand you said we can ignore them, but I find it interesting that it thinks one with an arg is valid, but not one without. Haven’t tested multiple args yet.

Back to expanding tests.

Another thing to note: You can set up an “on init()” method in your ASClass to set some values on instance variables, as opposed to just setting their value in the class script (like property testProperty : “Default value of testProperty”).

You just have to make sure to end it with “return me”. Otherwise you won’t get an instance of your object when the app starts.


property instanceVar : ""
property instanceUser : ""

on init()
	set my instanceVar to "Value of instanceVar set in init()"
	set my instanceUser to (short user name of (system info))
	return me
end init

I get warnings on them all.

Are you defining the handlers or relying on synthesized accessors from a property called objectVar? If the latter, they are only synthesized as instance methods.

I’ve played with this a bit, and I struggle to see the point. Strictly speaking any such handler should start with the AS equivalent of "self = [super init]"to initialize any instance variables in the superclass. But that’s not possible in AS. “[super init]” is equivalent to AS’s “continue init()”, but you can’t do the equivalent of "self = ".

You can leave this line out for subclasses of NSObject because there are no instance variables in the superclass to initialize, but it strikes me as potentially troublesome. It seems to me that we already have a way to initialize properties in AS, and we might as well use it and leave init to do any initialization of inherited properties/ivars.

But I’m open to persuasion on the issue…

Hmmm. How about this… Probably not a practical example, but let’s say we want to jazz up an NSButton in ASOC before sending it back to ObjC. NSButton inherits from a bunch of classes so it’s a good example of why you want to do a “self = [super init]” first. Who says our “on init()” in ASOC has to “return me”?.. Why not return a button you create? Not sure about using this in IB, but could be called with
NSButton *newFancyButton = [[myFancyButton alloc] init];


script myFancyButton
	property parent : class "NSButton"
	-- could just need to be NSObject, but seems that it
	-- might help when returned so the calling method
	-- doesn't bark about class type mis-match? Should
	-- at least conform to
	-- - (BOOL)isMemberOfClass:(Class)NSButton

	on init()
		set realButton to current application's class NSButton's alloc's init()
		-- realButton has been through "self = [super init]" ???
		tell realButton
			-- psuedo code
			-- many of these could differ for each instance
			setButtonType_(aType)
			setTitle_(aTitle)
			setKeyEquivalent_(charCode)
			setFont_(fontObject)
			setAlignment_(mode)
			-- etc, etc...
		end tell
		return realButton
		-- instead of "return me"
	end init
end script

Whatcha think?

Well, the only place the string “objectVar” shows up is (truncated code):


-- @interface ObjCClass : NSObject {
-(IBAction)setObjectVar:(id)sender;
-(IBAction)setObjectVarClass:(id)sender;

-- @implementation ObjCClass
-(IBAction)setObjectVar:(id)sender
	[myASClass setObjectVar: @"New value to put into var by instance method"];
-(IBAction)setObjectVarClass:(id)sender
	[[myASClass class] setObjectVar: @"New value to put into var by class method"];

-- script ASClass
on objectVar()
on setObjectVar_(tValue)

So it appears to me that it’s only because of the arg/parameter being used. Even set up a new set and go no warning, but moving on to more than one drew the same warning (unless I set up my ObjC code wrong… Newbie pains, you know?) :rolleyes:

Honestly? It scares me :slight_smile:

No, I meant how are you using it in the AS class.

Heh. Well, I think I’ll let that one go for now and cross that bridge when I get to it. Got other things in mind that I wanted to mix the two for… At least until it starts bugging me. :confused:

In the most basic of tests…


	property instanceVar : "Default Value"
	
	on objectVar()
		return my instanceVar
	end objectVar
	
	on setObjectVar_(tValue) -->> No error here in .m
		set my instanceVar to tValue
	end setObjectVar_

It gives the same error on:


	on setObjectVar_andAnother_(tValue1, tValue2)
		set my instanceVar to tValue1
		set my instanceVar2 to tValue2
	end setObjectVar_andAnother_

Other than that, all I do is some “log ” for testing so I can make sure things are doing what I hope they will.

FWIW, if you’d called your property objectVar, you wouldn’t have needed to write the first two accessors.

[Edit: See self realized correction in next post, too]

That worked for getting the value of the property from the instance, but failed getting it from the class:


property objectVar : "Default Value"

-- on objectVar()    commented out

[myASClass objectVar];
returnString = Default Value

[[myASClass class] objectVar];
+[ASClass objectVar]: unrecognized selector sent to class 0x1028a05a0

setObjectVar seems to work on both instance and class, but I can’t verify a change in class because of that error.

Also, I started with the original setting (using a different name for the property) thinking of future reference where the value to be returned could end up being the result of a handler/function inside the ASClass instead of just a property. Now that I know this, however, I guess I can keep both in mind.

Next is to see what happens when creating a new instance of ASClass with alloc/init (secondASClass)… If I set the value in the class using setObjectVarClass before creating a new instance, what would be the expected behavior when running [secondASClass objectVar]? I’m still too new to Obj-C and ASOC to know… Should it return the original “Default Value” that’s defined in the ASClass, or should it return the new value set by setObjectVarClass ahead of time (until app restart, I presume)?

If the new instance takes on the “Default Value” then I don’t really see any point of setting it to anything else in the class object itself.

Ahhhh. I see. I just read through some more basic docs… I now see that I needed to comment out BOTH

– on objectVar()
– setObjectVar()

Ok. That’s working right… At least for instance settings. Fails for both of the class types.

Right – because a property is a type of instance variable.