Утечки памяти в pushViewController и (я думаю) возвращение из очереди GCD - PullRequest
0 голосов
/ 24 сентября 2011

У меня проблемы с утечкой памяти на одном из моих контроллеров представления. Из моего основного контроллера просмотра я нажимаю свой контроллер просмотра настроек так:

-(IBAction)launchSettings {
    SettingsViewController *svc = [[SettingsViewController alloc] init];
    svc.title = @"title of app";

    //this actually adds a back button for the next vc pushed
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];

    [[self navigationController] pushViewController:svc animated:YES]; // <--Instruments says leak is here
    [svc release];

    if (AdsAreEnabled) {
        ADBannerView *adBanner = SharedAdBannerView;
        adBanner.delegate = nil;
    }    
}

Итак, когда я первоначально нажимаю на контроллер вида, у меня нет утечек. Контроллер представления использует очередь GCD для загрузки моего магазина покупок в приложении, и когда я нажимаю кнопку «назад», которую я создал выше, чтобы вытолкнуть ее из стека, это происходит, когда в инструментах появляется дрянь утечек. В строке кода появляется куча, где я нажимаю контроллер представления, что не имеет смысла для меня, так как я немедленно выпускаю его.

Пара других утечек протекает только в основном, либо NSCFstring s, SKProduct и SKProductInternal, которые, я думаю, возникают только в очереди GCD. Вот где инструменты говорят мне, что проблема:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil); // <-- Instruments says leak is here
    [pool release];
    return retVal;
}

Вот мой код, где я вызываю GCD, в своем собственном методе, который вызывается во время viewDidLoad из SettingsViewController:

if ([iapManager canMakePurchases]) {
    // Display a store to the user.
    iapTableView.sectionFooterHeight = 0;
    iapTableView.rowHeight = 50;
    iapTableView.scrollEnabled = NO;
    //init sectionNames here to avoid leakage.
    sectionNames = [[NSArray alloc] initWithObjects:@"Get Rid of Ads!", nil];
    [spinner startAnimating];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadStore) name:kInAppPurchaseManagerProductsFetchedNotification object:iapManager];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadStore) name:kTransactionCompleted object:iapManager];
    //Run this in seperate thread to avoid UI lockup
    dispatch_queue_t store_check = dispatch_queue_create("see if store is available", NULL);
    dispatch_async(store_check, ^ {
        [iapManager loadStore];
    });
    dispatch_release(store_check); 
}

Я немного озадачен тем, что я сделал здесь неправильно - я использую точно такую ​​же технику для загрузки другого контроллера представления, и он не протекает, и я не могу понять, как определить, / где мой материал GCD протекает - все неоднократно анализировалось и выходит чистым. Я удаляю своего наблюдателя из Центра уведомлений в dealloc SVC, так что это не так. Я удостоверился, что удалил наблюдателя транзакции в моем диспетчере IAP dealloc, так что это не так.

Есть предложения? Что-нибудь еще, что вам нужно знать, чтобы помочь мне понять, где я так ужасно ошибся?

Отредактировано, чтобы добавить: я выпускаю sectionNames в методе dealloc SVC, так что это тоже не так.

Редактировать 2: Я пробовал auto- releasing svc, когда я alloc его (и избавляюсь от соответствующего release), но я все еще получаю те же утечки.

Ответы [ 2 ]

2 голосов
/ 25 сентября 2011

Ну, я наконец-то понял это с помощью справки по устранению неполадок от друга - по какой-то причине я забыл, что вам все еще нужно release IBOutlet ivar, даже если вы не настроили его как property (по какой-то причине я подумал IBOutlet autoreleased, если это не было свойством, что неправда), и как только у меня были правильные выпуски в dealloc, все мои утечки волшебным образом исчезли.

Дух.Полагаю, еще одна вещь, которую нужно добавить в мой контрольный список идиотов.:)

Спасибо за предложения, ребята!

0 голосов
/ 24 сентября 2011

Прежде всего, в "launchSettings".Вы инициализировали UIBarButtonItem с помощью «alloc and init», что делает его retain count = 1, но вы не освободили его.

Вы должны понимать, что эти свойства сохраняют значения, переданные им.Таким образом, вы можете получить autoreleased.

Я должен сказать, что это действие не требуется, поскольку кнопка возврата уже установлена ​​для вас.

Во-вторых, в последнем фрагменте кода высделал то же самое sectionsName.

...