andreamazz / AMTagListView

UIScrollView subclass that allows to add a list of highly customizable tags.
MIT License
758 stars 110 forks source link

There's a retain cycle problem that causes memory leaks in AMTagListView #22

Closed Skogetroll closed 9 years ago

Skogetroll commented 9 years ago

Brief intro

My app uses your control on each view controller in UIPageViewController. Recently, I detected that there’s a memory leak when scrolling in PageViewController.

I’ve used CRChecker to detect possible retain cycles and troublesome controls, and the analysis indeed shows that your control definitely has this problem.

Possible sources

After brief source inspection I detected few possible sources:

There is link to self in both - [NSNotificationCenter addObserverForName:object:queue:usingBlock] and [NSArray enumerateObjectsUsingBlock:]. And blocks always retain all captured variables.

So now we have a strong reference to AMTagListView that keeps that object in memory until the block object is deallocated.

Possible solution

You should pass weak pointers to self, instead of strong ones.

But …

I’m not sure that the problem is limited to these two cases, so you should check your code further for any other possible sources of memory leaks.

mythodeia commented 9 years ago

@Skogetroll something like this should do the trick i changed the code and it works without issues and it seems i do not have any leaks

    __weak AMTagListView *weakSelf = self;
    self.orientationNotification = [center addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
        [weakSelf rearrangeTags];
    }];
    self.tagNotification = [center addObserverForName:AMTagViewNotification object:nil queue:nil usingBlock:^(NSNotification *notification) {
        if (weakSelf == notification.userInfo[@"superview"]) {
            if (_tapHandler) {
                weakSelf.tapHandler(notification.object);
            }
        }
    }];
andreamazz commented 9 years ago

Weird that something like this flew over my head. So weird that I had to checkout the git blame and.... Yep, that was me. :smile:
I'll fix it asap, thanks for the heads up