Strange AppleScript declare error

Currently I review some older projects to get them running on 64-bit.
Now I have a strange error and no idea what’s wrong.

I call AppleScript (Xojo 2019r1.1 on macOS 10.14.15) via declares (as shown in Proper way to execute an AppleScript? .
It worked fine in past but now I get a strange error.
Simplified example:
In a push button’s action event paste following code

[code]Soft Declare Function NSClassFromString Lib “Cocoa” (classname As CFStringRef) As ptr
Soft Declare Function initWithSource Lib “Cocoa” selector “initWithSource:” (obj As ptr,source As CFStringRef) As ptr
Soft Declare Function executeAndReturnError Lib “Cocoa” selector “executeAndReturnError:” (obj As ptr,ByRef error As ptr) As ptr

Dim theScript As String = “tell application ““Finder”” to close window ““test”””
Dim ASClass As Ptr = NSClassFromString(“NSAppleScript”)
Dim scr As ptr
scr = initWithSource(ASClass,theScript)
Catch e As RuntimeException
System.Log System.LogLevelError, "Got an Exception " + Str(e.ErrorNumber)
System.Log System.LogLevelError, e.Message

Dim err As ptr
Dim descriptor As ptr = executeAndReturnError(scr, err)
If descriptor = Nil Then
Dim e As RuntimeException
e.Message = “Can’t execute AppleScript!”
End If [/code]
Now open a Window “test” in Finder and run the application. The window should be closed.

I get an exception [quote]+[NSAppleScript initWithSource:]: unrecognized selector sent to class 0xa8539240[/quote]

I have no idea what’s wrong here because it worked well in past.
Any clues?

initWithSource: is an instance constructor: You cannot call it on the class but on an allocated instance of it.
Your code is missing the alloc(Classptr) method that was included in the original you linked.

1 Like

Thanks. You’re right.
I did not look and thought that an init… must be a class method.
A typical “This can’t be wrong” error :wink:

You’re welcome.

It is exactly the other way:
If you encounter any ObjectiveC constructor that has the class it is name – in this case, if it would exist, it were appleScriptWithSource: –, then you could be quite sure to have a class constructor.
Another indicator would be the (+) sign in Apple’s ObjC documentation.

If I may just expand on this to emphasize something. Whenever you copy and paste Objective-C declares you should follow this rule.

If the code includes a “init” & “alloc” pair, you are responsible for releasing this object when you’re done with it. Failure do so will result in memory leaks. So check and make sure that there is a “release” at or near the end.

On the other hand; if the code uses a class constructor as illustrated by @Ulrich Bogun, you should call “retain” on the object notifying the system that it should keep this object in scope, then followed by “release” when you’re done. Failure to “retain” an object means the OS will release it at the end of the current cycle, failure to release it will lead to a memory leak.

Don’t call “retain” on an object that’s created via “init” & “alloc”, otherwise you’ll need to call release at least twice. Once an object has been released, trying to access it will lead to a crash.

Also be sure to read the whole conversation, as issues like these tend to get worked out into a more fully fledged example.
See Joe Ranieri’s version of the code. It handles autorelease and errors properly.