NSCalendar declare

Good afternoon.

I have a need to use the iOS NSCalendar class. Need to be able to convert between Gregorian, Hebrew, and Islamic calendars.

I can create an object:

Declare Function NSClassFromString lib “Foundation”(cname as CFStringRef) as Ptr

I can get the current calendar:

Declare Function currentCalendar Lib “Foundation” Selector “currentCalendar” (NSCalendarClass As Ptr) As Ptr

I can get the calendarIdentifier:

Declare Function calendarIdentifier Lib “Foundation” Selector “calendarIdentifier” (NSCalendar as Ptr) as CFStringRef

What I can’t do (reliably crashes) is init to the desired calendar:

Declare Function initWithCalendarIdentifier lib “Foundation” Selector “initWithCalendarIdentifier:”(o as Ptr, name as CFStringRef) as Ptr

So if we have:

dim g1 as Ptr
dim g2 as Ptr

g1 = NSClassFromString(“NSCalendar”) // this works
g2 = initWithCalendarIdentifier(gregorian,“gregorian”) // crash. (the “gregorian” is what is returned from the calendarIdentifier method


Whenever you see init… for a class, you have an instance constructor method. in these cases you have to allocate the memory for the object (that’s

Declare Function Alloc lib "Foundation" selector "alloc" (id as ptr) as ptr)

so your method would have to be

g2 = initWithCalendarIdentifier(alloc(g1),"gregorian")

Edit: instance constructors create an object already retained. If you’d create calendars often keep an eye at Activity monitor for memory leaks – in these cases

Declare Sub Release lib "Foundation" selector "release" (id as ptr) helps – release g2 when you don’t need it anymore in that case.


I’ll check this right away.

Back in a bit.

Two minutes later: That solved it.

Thank you.

Question: Are you saying that when the class I’m creating goes out of scope alloc’d things are not automatically released? If so, I need to release it. (No automatic reference counting in Declares?).

Only the Xojo side is released by Xojo’s ARC – your ptr g2 in that case. It does not transfer to the object you created in memory by your declare. It is an object managed by the OS, not by Xojo, therefore the ARC does not transfer. They are two independent ARC mechanisms.

For iOS (and macOS) objects that use a class constructor – you usually recognize them by having the classname in their name, and by the + symbol at the beginning of their objC reference in Apple’s developer docs –, you usually don’t need to worry because class constructors create unretained objects, so they live only as long as the ptr you declare them to is alive. (In some cases you have to retain them manually, like when you want to forward them to other methods.)

(That’s, btw, one of the reasons I prefer declare libraries like the old MacOSLib (or, of course, my AppleLib). The classes created in them contain logic to release their object once it gets out of scope.
For some simple declares rarely used, this is usually no problem. It can become difficult when you try to declare a complete framework.)