pushViewController中的内存泄漏和(我认为)从GCD队列返回

时间:2011-09-23 20:58:20

标签: ios memory-management viewcontroller grand-central-dispatch

我在其中一个视图控制器上遇到内存泄漏问题。从我的主视图控制器,我正在推动我的设置视图控制器:

-(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队列来加载我的应用程序内购买商店,当我点击上面创建的“后退”按钮将其从堆栈中弹出时,就是当仪器中出现泄漏的大量泄漏时。在我推动视图控制器的代码行中出现了一堆,这对我来说没有意义,因为我立即释放它。

其他几个泄漏只在主要版本中泄漏,NSCFstringSKProductSKProductInternal,我认为所有泄漏只会在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的{​​{1}}期间调用自己的方法:

SettingsViewController

我有点难过这里我做错了什么 - 我使用完全相同的技术加载一个不同的视图控制器,它不会泄漏,我无法弄清楚如何判断是否/我的GCD东西泄漏了 - 所有的东西都经过反复分析并且干净利落。我从SVC的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); } 中的通知中心删除了我的观察者,所以不是这样。我确保在我的IAP经理dealloc中删除了交易观察者,所以不是这样。

有什么建议吗?还有什么你需要知道的,以帮助我弄清楚我在这里走得非常糟糕的地方吗?

编辑添加:我在SVC的dealloc方法中发布了sectionNames,所以它也不是。

编辑2:我尝试了自动dealloc svc releasing它(并删除相应的alloc)但我仍然遇到相同的泄漏。

2 个答案:

答案 0 :(得分:2)

好吧,我终于通过朋友的一些故障排除帮助弄明白了 - 出于某种原因,我忘了你仍然必须release IBOutlet ivar,即使你没有把它设置为property(由于某种原因,我认为IBOutlet autoreleased如果它不属于某个属性,那是不正确的),并且一旦我在dealloc中获得了正确的版本,我所有的泄漏都神奇地消失了。

咄。我想,另外一件事要添加到我的白痴清单中。 :)

感谢您的建议,伙计们!

答案 1 :(得分:0)

首先,在“launchSettings”中。你已经通过“alloc and init”初始化了UIBarButtonItem,这使得它的retain count = 1但你还没有释放它。

您应该意识到这些属性保留了传递给它们的值。所以你可以autoreleased

我应该说不需要这个动作,因为已经为你提供了后退按钮。

其次,在最后一个代码段中,您执行了相同的sectionsName