Ios pushViewController内存泄漏,并且(我认为)从GCD队列返回
我的一个视图控制器出现内存泄漏问题。在我的主视图控制器中,我按下设置视图控制器,如下所示:Ios pushViewController内存泄漏,并且(我认为)从GCD队列返回,ios,memory-management,viewcontroller,grand-central-dispatch,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 sel
-(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的代码,在设置视图控制器的查看加载期间调用它自己的方法:
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东西是否/在哪里泄漏-所有东西都经过反复分析,结果都是干净的。我在SVC的dealloc
中将我的观察者从通知中心移除,所以不是这样。我确保在我的IAP经理的dealloc
中删除了事务观察者,所以不是这样
有什么建议吗?你还需要知道些什么来帮助我找出我在这里犯了如此严重的错误
编辑添加:我在SVC的dealloc
方法中发布了sectionNames,所以也不是这样
编辑2:我尝试了自动释放svc,当我释放它时(并去除相应的释放),但我仍然得到同样的泄漏。首先,在“启动设置”中。您已经通过“alloc和init”初始化了uibarbuttonite,这使得它的retain count=1,但您还没有释放它
您应该意识到这些属性保留了传递给它们的值。因此,您可以将其自动删除
我应该说,这个动作是不需要的,因为后退按钮已经为您设置好了
其次,在上一个代码片段中,您做了相同的部分sname
好吧,我最终在朋友的一些故障排除帮助下解决了这个问题-出于某种原因,我忘记了您仍然必须发布一个IBOutlet
ivar,即使您没有将它设置为属性
(出于某种原因,我认为一个IBOutlet
autoreleased
,如果它不是一个属性,这是不正确的),一旦我在dealloc
中获得了适当的释放,我所有的泄漏就神奇地消失了
嗯。我想我的白痴清单上还有一件事要补充。:)
谢谢你们的建议,伙计们 sectionNames
是泄漏,请先调用release或使用属性,然后使用自动释放的数组。记住viewDidLoad
可以多次调用。不,没有骰子。我在dealloc
中发布了sectionNames
,因为在加载显示存储的tableView的其余部分时,我需要再次访问它,但出于某种原因,我只使用了ivar而不是属性。我把它作为一个属性添加了进来,看看它是否修复了它,一开始它看起来像修复了一样,但是没有,仍然会泄漏。这并不能解决你的问题,但这仍然是一个泄漏,即使你在dealoc
中释放它,你仍然需要在再次分配它之前释放它。我有点困惑——就我所见,只分配了一次,就在这里。然后,当我重新加载tableView的数据时,我只需再次访问它(此时,它只是为UITableViewStyleGrouped
tableView的sectionHeader读取。如果稍后我给它一个不同的名称,我会释放它,但我只是在这里给它一个名称,这样当存储加载正在旋转时,当我有一个旋转器时,这个名称就会显示出来。嗨,莫汉纳德,实际上,uibarbuttonite是alreadyautoreleased
,如果你看那行代码的末尾。我这样做是为了让它实际上读“Back”,而不是上一个视图控制器的默认标题(相当长).我还将在dealloc
中添加一条关于发布sectionNames的注释,因为我这样做了,这似乎是一些人认为的问题所在。
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);
}