Hemang Hemang - 3 months ago 17
Objective-C Question

iOS : ".cxx_destruct" - a hidden selector in my class

I used the answer of this question, List selectors for obj-c object and list out all the selectors to which my class object is responding. In a huge list I found a selector named ".cxx_destruct" (yes, it's start with a dot), I am seeing this for the first time, and never heard about it too. I googled for it and found this Objective C: ARC errors (Automatic release problems).

I've some questions in my mind?


  • Is it related to ARC?

  • If its a selector why its hidden?

  • When it'll call? By whom, an iOS itself?

  • Why its named like .cxx_destruct? what's the full form of "cxx".. ?


Answer

Prior to ARC, developers would have to deliberately write a dealloc routine to ensure that all the references to all the objects they retained were released. This was manual and error-prone work.

When ARC was introduced code that performs an equivalent task as these manual releases would have to be implemented in each object that possessed anything more than simple properties. Relying on a developer manually implementing a dealloc routine would defeat this.

Note: This is just for the purposes of reference count management when destroying objects. If you need to remove observers or perform other cleanup work, then you'll still need a dealloc routine.

As a result, the pre-existing mechanism from objective-c++ was used, namely a hidden selector called .cxx_destruct which is invoked automatically just prior to the object being deallocated. This selector is invoked automatically by the Objective C run-time.

For Objective C++ code, there is a parallel .cxx_construct for construction.

Again, these are automatically generated by the compiler to deal with object destruction in the ARC context. You can see it being created if you compile some simple objective C code with and without an object property. Take this sample code:

#import <Foundation/Foundation.h>

@interface Foo : NSObject

@property (strong) NSObject *anobject;

@end

@implementation Foo
@end

int main()
{
    Foo *f = [[Foo alloc] init];
    return 0;
}

When we compile with ARC (clang -fobjc-arc test.m -o test -framework foundation) and dump the class information we see a .cxx_destruct selector, when we compile without ARC (clang -fnoobjc-arc test.m -o test -framework foundation), we do not see a .cxx_destruct selector. If you comment out the NSObject *anobject property and recompile, you will not see the .cxx_destruct as it is no longer needed.