Objective-C release property declared in category?

I have a category in an existing class that adds a property and several methods to the class.

@interface AClass (ACategory) { NSString *aProperty; } @property (nonatomic, retain) NSString *aProperty; @end 

In the implementation file, I want to free this property when the object is freed. However, if I declare dealloc in this class, it will override dealloc from the source class from what I understand. What is the correct way to free this aProperty when the object is freed?

 @implementation AClass (ACategory) @synthesize aProperty; - (void)dealloc { [aProperty release]; // this will skip the original dealloc method from what I understand [super dealloc]; } @end 
+6
objective-c dealloc objective-c-category
source share
2 answers

Well, this is a bit problematic, as your code is wrong.

  • You cannot declare instance variables in a category; using the latest Objective-C ABI, you can declare new instance variables inside the class extension ( @interface AClass () {//... ), but this is different from the category ( @interface AClass (ACategory) ).
  • Even if you could, the syntax for declaring an instance variable is that they are enclosed in braces after the @interface string.

You can declare a property in a category, but you need to define its store without using a new instance variable (hence @dynamic instead of @synthesize ).


As for your actual question, you cannot call the initial implementation of the overridden method unless you use the swizzling method (facilitated by run-time functions like method_exchangeImplementations ). I do not recommend doing this at all; it is really scary and dangerous.


Update: Explanation of instance variables in class extensions

A class extension is similar to a category, but it is anonymous and must be placed in the .m file associated with the source class. It looks like this:

 @interface SomeClass () { // any extra instance variables you wish to add } @property (nonatomic, copy) NSString *aProperty; @end 

Its implementation should be in the main @implementation block for your class. Thus:

 @implementation SomeClass // synthesize any properties from the original interface @synthesize aProperty; // this will synthesize an instance variable and accessors for aProperty, // which was declared in the class extension. - (void)dealloc { [aProperty release]; // perform other memory management [super dealloc]; } @end 

Thus, extending a class is useful for storing variables and methods of a private instance from the public interface, but it will not help you add instance variables to a class that you do not control. There is no problem with overriding -dealloc , because you simply implement it, as usual, with any necessary memory management for the instance variables entered in the class extension.

Please note that this material only works with the latest 64-bit Objective-C ABI.

+12
source share

As an aside, you can use related links to "simulate adding instance variables to an existing class."

Essentially, you can add a related object as shown below:

 static void* ASI_HTTP_REQUEST; // declare inside the category @implementation but outside any method // And within a method, init perhaps objc_setAssociatedObject(self, &ASI_HTTP_REQUEST, request, OBJC_ASSOCIATION_RETAIN); 

And release the related object by sending 'nil':

 // And release the associated object objc_setAssociatedObject(self, &ASI_HTTP_REQUEST, nil, OBJC_ASSOCIATION_RETAIN); 

Apple documentation here .

It took me a while to find, so I hope this helps someone.

+5
source share

All Articles