开发者

Is there a way to enumerate all properties and release them one by one?

Typical dealloc

Well it sucks. What about if I forget a property to dealloc?

Why can't we have something like dealloc All properties

Worst of all, I sort of like the way viewControllers are handled now. We put a property and poof the dealloc is put. Can't have that on normal classes ha?

- (void)dealloc
{
    [_window release];
    [__managedOb开发者_运维百科jectContext release];
    [__managedObjectModel release];
    [__persistentStoreCoordinator release];
    [_MainBadgerApplication release];
    [_SettingsMiscelaneous release];
    [_theNearByIsiKota release];
    [Customcell release];
    [PhoneCC release];
    [searchViewController release];
    [_superTabBar release];
    [_SuperNavBar release];
    [pinNumberView release];
    [_lblForPinNumber release];
    [navController release];
    [NearbyShortcut release];
    [_searchListView release];
    [_searchNearView release];
    [LoadingView release];
    [super dealloc];
}

I am thinking of a macro where I can just do

myDealloc

and that will enumerate all properties and release them one by one or set them to nil (which is almost equivalent)


This looks like a horrible idea, so here is the code :D This will step through every object property on your code and send a release. I didn't compile it, but it's more or less like this.

#import <objc/runtime.h>

unsigned int propertyCount;
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
for (unsigned int i = 0; i < propertyCount; i++)
{
    SEL sel = @selector(release);
    const char *attr = property_getAttributes(properties[i]);
    switch (attr[1]) {
        case '@':
            property_getName(properties[i]), objc_msgSend(self, sel)]
            break;
        default:
            break;
    }
}
free(properties);

You can wrap it in a C function and call it from your dealloc.


You are not enumerating properties here, but instance variables (that may be the backing variables associated by properties, sure, but maybe not, you didn't give the code that declares the properties so we cannot know)

My suggestion:

  • Use the ability of the modern runtime (used by iOS since iOS exists -- and by OSX only in 64 bits) to automatically generate the backing store of properties. Thus you won't need to declare instance variables for your properties in the header file, and won't be tempted to use the instance variable directly instead of the property
  • In the dealloc -- and in the viewDidUnload method for properties that are bound to IBOutlets -- set your @properties to nil (instead of releasing the ivar
  • Finally, once you are managing your properties this way, this will be possible to set all of your properties to nil by introspection.

Once your are doing like explained above, You can use introspection: use the functions of the Objective-C Runtime to get every @property of a given class, then look thru them and set them to nil (which will release the memory of the backing variable associated with the @property)


I would suggest an alternative approach. Firstly, setting properties to nil in either the init or the dealloc goes against Apple's guidelines. This is because you could be invoking a setter method. For example if the developer has overridden the standard property setter and defined a custom setter method.

In that case, invoking such a method during an init or dealloc can give unpredictable results.

Better to invoke [myIvar release]; as normal.

To track down missing release statements, run the Analyzer. Or, even better, set the target's build settings to always run Analyzer when you do a build.

Finally, it's worthwhile periodically running your app in Instruments. That will pick up leaks and will save you time in tracking down strange bugs that would otherwise happen with the leaked memory.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜