gpt4 book ai didi

iphone - "EXC_BAD_ACCESS", "-[CFString retain]: message sent to deallocated instance"在表格中滚动时

转载 作者:行者123 更新时间:2023-12-03 19:31:18 25 4
gpt4 key购买 nike

应用程序描述:我是一名新的 iPhone 开发人员。我正在开发一个使用两个 TableView 然后一个详细 View 的应用程序。第一级表格 View 呈现几个类别,当选择一个类别时,将显示与该类别相关的主题列表。选择主题后,将显示与该主题相关的详细 View 。

当我在模拟器中运行应用程序时,一切似乎都工作正常(但只是短暂!):

  • 第一级表格 View :此带有类别的 View 加载良好且工作正常,没有任何问题。
  • 主题 ListView :此 View 似乎也可以正常工作,但只是短暂的。它加载所有正确的主题,我什至可以快速上下滚动浏览整个主题列表 - 但这只能在滚动时持续几秒钟(之后应用程序崩溃)。我还可以选择任何主题,并且详细 View 会成功加​​载。
  • 详细 View :工作正常,没有问题。

我在应用程序中使用两个 Nib :MainWindow.xib 显示第一级和主题 View 表。 TopicDetail.xib 用于显示主题的详细信息。

数据: 第一级 View 从包含字符串数组的 plist 中获取数据。主题 ListView 从字典 plist 中获取数据。每个字典由五个字符串组成。这些字符串之一包含与主题相关的类别的“标签”。当选择第一级 View 中的类别时,主题 View 会选择与所选类别匹配的带有“标签”的主题,并将它们显示在主题 View 表中。

问题:我的问题是第二个“主题 View ”。我导致崩溃的几种方式:

  • 如果我快速上下滚动主题列表,几秒钟内一切正常,然后应用程序就会崩溃。

  • 如果我将一个单元格滚动出屏幕,我可以毫无问题地将同一单元格滚动回屏幕上。如果我重复此操作(再次将同一单元格从屏幕上滚动,然后尝试将其滚动回屏幕上),则当将单元格滚动回屏幕上时,应用程序会崩溃。

错误消息:返回的初始错误消息是EXC_BAD_ACCESS。当我启用 NSZombieEnabled 时,我收到错误消息“-[CFString keep]:消息发送到已解除分配的实例

根据这些错误消息和我的研究,我相信我遇到了内存分配问题,即在已释放的对象上调用“retain”,但我无法弄清楚发生这种情况的位置以及如何解决它!任何帮助将不胜感激 - 提前谢谢您!!

代码:

第一级 View Controller .h:

#import 
@class TopicListController;

@interface FirstLevelViewController : UITableViewController {
NSArray *controllers;
TopicListController *childController;
}
@property (nonatomic, retain) NSArray *controllers;
@end

第一级 View Controller .m:


#import "FirstLevelViewController.h"
#import "TopicListController.h"
#import "TopicAppDelegate.h"

@implementation FirstLevelViewController
@synthesize controllers;

- (void)viewDidLoad
{
self.title = @"Categories";
NSString *path = [[NSBundle mainBundle] pathForResource:@"TopicCategoryList" ofType:@"plist"];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.controllers = array;
[array release];
[super viewDidLoad];
}

- (void)viewDidUnload
{
self.controllers = nil;
[childController release];
childController = nil;
[super viewDidUnload];
}

- (void) dealloc
{
[controllers release];
[childController release];
[super dealloc];
}

#pragma mark -
#pragma mark Table Data Source Methods

- (NSInteger)tableView:(UITableView *)tableview numberOfRowsInSection:(NSInteger)section
{
return [self.controllers count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell = @"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];

if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [controllers objectAtIndex:row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}

#pragma mark -
#pragma mark Table View Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (childController == nil) {
childController = [[TopicListController alloc] init];
}

childController.title = @"Topics";
NSUInteger row = [indexPath row];

NSString *selectedCategory = [self.controllers objectAtIndex:row];
childController.selectedCategory = selectedCategory;
[self.navigationController pushViewController:childController animated:YES];
}

@end

主题列表Controller.h:

#import 
@class TopicDetailController;

@interface TopicListController : UITableViewController {

NSArray *list;
NSString *selectedCategory;
TopicDetailController *childController;

}

@property (nonatomic, retain) NSArray *list;
@property (nonatomic, retain) NSString *selectedCategory;

@end

主题列表 Controller .m

#import "TopicListController.h"
#import "TopicAppDelegate.h"
#import "TopicDetailController.h"
#import "NSArray-MutableDeepCopy.h"
#import "TopicConstants.h"

@implementation TopicListController

@synthesize list;
@synthesize selectedCategory;

- (void)viewWillAppear:(BOOL)animated
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"TopicContent" ofType:@"plist"];

NSMutableArray *fullArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSMutableArray *fullArrayCopy = [fullArray mutableDeepCopy];

NSUInteger items = [fullArrayCopy count];
NSUInteger item=0;

for (item; item /*less than*/ items; item++) {
if ([[[fullArrayCopy objectAtIndex:item] objectForKey:CATEGORIES_KEY]
rangeOfString:selectedCategory
options:NSCaseInsensitiveSearch].location == NSNotFound)
{
[fullArrayCopy removeObjectAtIndex:item];
item--;
items--;
}
}

self.list = fullArrayCopy;
[fullArray release];
[self.tableView reloadData];
[super viewWillAppear:animated];
}

- (void)viewDidUnload
{
self.list = nil;
self.selectedCategory = nil;
[childController release];
childController = nil;
}

- (void)dealloc
{
[list release];
[selectedCategory release];
[childController release];
[super dealloc];
}

#pragma mark -
#pragma mark Table Data Source Methods

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
return [list count];
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
static NSString *DisclosureButtonCellIdentifier = @"DisclosureButtonCellIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DisclosureButtonCellIdentifier];

if (cell==nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:DisclosureButtonCellIdentifier]
autorelease];
}

NSUInteger row = [indexPath row];
NSString *rowString = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
NSString *rowDetailString = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
cell.textLabel.text = rowString;
cell.detailTextLabel.text = rowDetailString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
[rowString release];
[rowDetailString release];
return cell;
}

#pragma mark -
#pragma mark Table Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (childController == nil) {
childController = [[TopicDetailController alloc] initWithNibName:@"TopicDetail" bundle:nil];
}


NSUInteger row = [indexPath row];

NSString *selectedTopicInformation = [[list objectAtIndex:row] objectForKey:INFORMATION_KEY];
NSString *selectedTopicTitle = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
NSString *selectedTopicSubtitle = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
NSString *selectedTopicTips = [[list objectAtIndex:row] objectForKey:TIPS_KEY];

NSString *detailMessageInformation = [[NSString alloc] initWithFormat:@"%@.", selectedTopicInformation];
NSString *detailMessageTitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicTitle];
NSString *detailMessageSubtitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicSubtitle];
NSString *detailMessageTips = [[NSString alloc] initWithFormat:@"%@", selectedTopicTips];

childController.messageInformation = detailMessageInformation;
childController.messageTitle = detailMessageTitle;
childController.messageSubTitle = detailMessageSubtitle;
childController.messageTips = detailMessageTips;

childController.title = @"Topic Detail";

[detailMessageInformation release];
[detailMessageTitle release];
[detailMessageSubtitle release];
[detailMessageTips release];
[self.navigationController pushViewController:childController animated:YES];


}

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
if (childController == nil) {
childController = [[TopicDetailController alloc] initWithNibName:@"TopicDetail" bundle:nil];
}

NSUInteger row = [indexPath row];

NSString *selectedTopicInformation = [[list objectAtIndex:row] objectForKey:INFORMATION_KEY];
NSString *selectedTopicTitle = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
NSString *selectedTopicSubtitle = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
NSString *selectedTopicTips = [[list objectAtIndex:row] objectForKey:TIPS_KEY];

NSString *detailMessageInformation = [[NSString alloc] initWithFormat:@"%@.", selectedTopicInformation];
NSString *detailMessageTitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicTitle];
NSString *detailMessageSubtitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicSubtitle];
NSString *detailMessageTips = [[NSString alloc] initWithFormat:@"%@", selectedTopicTips];

childController.messageInformation = detailMessageInformation;
childController.messageTitle = detailMessageTitle;
childController.messageSubTitle = detailMessageSubtitle;
childController.messageTips = detailMessageTips;

childController.title = @"Topic Detail";

[detailMessageInformation release];
[detailMessageTitle release];
[detailMessageSubtitle release];
[detailMessageTips release];
[self.navigationController pushViewController:childController animated:YES];
}

@end

最佳答案

您的问题出在tableView:cellForRowAtIndexPath:中。您不应发布以下内容:

[rowString release];
[rowDetailString release];

当你得到如下字符串时:

NSString *rowString = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
NSString *rowDetailString = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];

它们作为自动释放的对象返回。你应该只释放你拥有的东西,即你从 new 开始的方法中分配、保留或获取的东西。解释这一点的好文章是 objective-c memory management for lazy people 。但引用重要的部分:

  • You own it if you alloc it.
  • You own it if you copy it.
  • You own it if you new it. (New is simply a shortcut for alloc/init).

关于iphone - "EXC_BAD_ACCESS", "-[CFString retain]: message sent to deallocated instance"在表格中滚动时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4412067/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com