简体   繁体   中英

Bug dynamically subclassing a UIViewController

Summary

I am trying to dynamically subclass objects to do some cleanup before dealloc. I add a subclass to the object and add my own dealloc method that does the cleanup and then calls [super dealloc] . This works for most cases but I am running into something strange when it happens to UIViewControllers. It seems some cleanup is not happening in dealloc because I am getting a crash when -hash is being sent to a deallocated view controller.

This happens when creating a view for a new view controller and it is growing some hash set in a class method of UIViewController. It seems to be a hash of view controllers for views because it is in a method +[UIViewController setViewController:forView:].

If I do not do the add my own dealloc method to the dynamic subclass everything is fine. Even if I only call [super dealloc] in my own version of dealloc it crashes the same way.

Does anyone have any idea what could be going wrong? Do I need to do something else other than calling [super dealloc] so that it still executes everything it should?

The Code

The dealloc method looks like this:

- (void)deallocWithRemoveAllAssociatedBindings {
    [[BindingManager sharedInstance] removeAllBindingsAssociatedWithObject:self];

    [super dealloc];
}

My dynamic swizzling method looks like this:

+ (void)createSubclassForObject:(id)object {
    Class objectClass = object_getClass(object);
    NSString *objectClassString = NSStringFromClass(objectClass);
    NSString *subclassName = [NSString stringWithFormat:@"RemoveAllAssociatedBindings_%@", objectClassString];

    Class subclass = objc_getClass([subclassName UTF8String]);
    if (!subclass) {
        subclass = objc_allocateClassPair(objectClass, [subclassName UTF8String], 0);
        if (subclass) {
            Method dealloc = class_getInstanceMethod(self, @selector(deallocWithRemoveAllAssociatedBindings));
            class_addMethod(subclass, @selector(dealloc), method_getImplementation(dealloc), method_getTypeEncoding(dealloc));
            [self addRemoveMethodToClass:subclass];
            objc_registerClassPair(subclass);
        }
    }

    if (!!subclass) {
        object_setClass(object, subclass);
    }
}

You can see the full code on github: https://github.com/drewag/property-bindings

you are never supposed to call dealloc on your own, thats apple's job. my suggestion would be to override the standard dealloc method and add what ever checks you need with an if statement to do your "custom dealloc" stuff. or you could just call your custom dealloc from inside dealloc just like how [super dealloc] is called... or just use ARC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM