gpt4 book ai didi

ios - UITableViewController : Objects properties deallocated

转载 作者:行者123 更新时间:2023-11-29 12:44:01 25 4
gpt4 key购买 nike

我正在使用 UITableViewController 来显示来自 Web 服务的文章列表。检索到数据后,将调用此委托(delegate)方法:

-(void)itemsDownloaded:(NSArray *)items
{
// Set the items to the array
_feedItems = items;

// Reload the table view
[self.tableView reloadData];
}

我还使用自定义单元格,以便标签的高度发生变化,因此使用以下代码显示整个文章的标题(遵循本教程 Table View Cells With Varying Row Heights):

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}

- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell isKindOfClass:[CustomTableViewCell class]])
{
CustomTableViewCell *textCell = (CustomTableViewCell *)cell;

Article *article_item = _feedItems[indexPath.row];

NSString *fulltitle = article_item.Title;

// fulltitle = article_item.Cat_Name; // testing category name

if (article_item.Subtitle != nil && article_item.Subtitle.length != 0) {
fulltitle = [fulltitle stringByAppendingString:@": "];
fulltitle = [fulltitle stringByAppendingString:article_item.Subtitle];
}
textCell.lineLabel.text = fulltitle;

textCell.lineLabel.numberOfLines = 0;
textCell.lineLabel.font = [UIFont fontWithName:@"Novecento wide" size:12.0f];
}
}



- (CustomTableViewCell *)prototypeCell
{
NSString *cellIdentifier = @"BasicCell";

if (!_prototypeCell)
{
_prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
}
return _prototypeCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];

self.prototypeCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(self.prototypeCell.bounds));

[self.prototypeCell layoutIfNeeded];

CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height+1;
}

第一个问题是 forRowAtIndexPath 方法被调用了两次而不是一次。因此,如果 _feeditems 有 10 个对象,该方法将被调用 20 次。第二次调用该方法时,我得到了 Article 对象 null 的两个属性(IDCat_Name) > 自解除分配以来:

*** -[CFString retain]: message sent to deallocated instance 0x9c8eea0
*** -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x9c8e370

这会在尝试显示类别名称时触发 EXC_BAD_ACCESS

我不确定到底是什么问题,我尝试删除代码以改变标签的高度,使用以下代码查看是否是导致此问题的原因:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Retrieve cell
NSString *cellIdentifier = @"BasicCell";
UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

// Get article
Article *item = _feedItems[indexPath.row];

myCell.textLabel.text = item.Title;

return myCell;
}

唯一的区别是,如果 _feeditems 有 10 个对象,则该方法被调用一次意味着调用 10 次。但是 Article 的属性 IDCat_Name 仍在被释放。

在获取数据时,_feeditems 中所有对象的属性都完好无损,没有任何释放。我猜它发生在 cellForRowAtIndexPathforRowAtIndexPath 中。

更新

正如@Ilya K 所建议的那样,不从 tableView:heightForRowAtIndexPath 调用 configureCell:forRowAtIndexPath: 可以解决调用两次的问题。我也试过拥有 feedItems 的属性。到目前为止,这是在 Controller (TableViewController.m) 的 @interface 中设置的:

@interface TableViewController () {
HomeModel *_homeModel;
NSArray *_feedItems;
Article *_selectedArticle;
}

我已将其从界面中删除并将其添加为属性 (TableViewController.h):

@interface TableViewController : UITableViewController <HomeModelProtocol>
@property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
@property (nonatomic, strong) CustomTableViewCell *prototypeCell;
@property(nonatomic) NSString *type;
@property(nonatomic) NSString *data;
@property(copy) NSArray *_feedItems;
@end

尽管如此,它仍在提供已解除分配的消息。

更新 2

我已经使用 InstrumentsZombie 模板查看了代码(感谢这个问题的回答 ViewController respondsToSelector: message sent to deallocated instance (CRASH) )。这是我从 Instruments 得到的错误:

Zombie Messaged

An Objective-C message was sent to a deallocated 'CFString (immutable)' object (zombie) at address: 0x10c64def0

enter image description here

所有 Release/Retain Event Types 都指向以下方法,connectionDidFinishLoading,当从 Web 服务检索 JSON 数据并创建 时会使用该方法检索到的每篇文章的文章对象:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Create an array to store the articles
NSMutableArray *_articles = [[NSMutableArray alloc] init];

// Parse the JSON that came in
NSError *error;

// Highlighted in blue
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:_downloadedData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:@"result"];

// Loop through Json objects, create question objects and add them to our questions array
for (int i = 0; i < fetchedArr.count; i++)
{
NSDictionary *jsonElement = fetchedArr[i];

// Create a new location object and set its props to JsonElement properties
Article *newArticle = [[Article alloc] init];
newArticle.ID = jsonElement[@"ID"];
newArticle.Title = jsonElement[@"Title"];
newArticle.Subtitle = jsonElement[@"Subtitle"];
newArticle.Content = jsonElement[@"Content"];
newArticle.ImageUrl = jsonElement[@"ImageUrl"];
newArticle.Author = jsonElement[@"Author"];
newArticle.PostId = jsonElement[@"PostId"];
newArticle.ArticleOrder = jsonElement[@"ArticleOrder"];
newArticle.Cat_Id = jsonElement[@"CategoryId"];
// Highlighted in yellow
newArticle.Cat_Name = jsonElement[@"CategoryName"];

// Add this article object to the articles array
// Highlighted in yellow
[_articles addObject:newArticle];
}

// Ready to notify delegate that data is ready and pass back items
if (self.delegate)
{
[self.delegate itemsDownloaded:_articles];
}
}

但我仍然无法弄清楚哪里出了问题。

更新 3

关于connectionDidFinishLoading 的更多测试我已经删除了正在解除分配的两个属性,并且未显示解除分配的消息。我不知道是什么原因导致这两个属性(IDCat_Name)被释放,此时无法从任何地方访问它们。

最佳答案

您不需要调用 configureCell:forRowAtIndexPath: 从 tableView:heightForRowAtIndexPath: 您应该使用带有 sizeWithAttributes 的 Article 对象来确定单元格高度:

您的 prototypeCell 函数只是创建类型为 CustomTableViewCell 的不相关的空单元格,没有必要尝试重新调整它的大小。

tableView:cellForRowAtIndexPath:每次您的 tableview 需要重绘时调用,例如当您滚动时。这意味着你的 _feeditems 数组应该被分配并保持一致,以便在实例生命周期的任何时间点与 UITableView 一起工作。

还要确保为 _feeditems 声明一个属性并使用该属性分配数据。

例子:@property (strong) NSArray *feeditems;或@property(复制)NSArray *feeditems;

在已下载的项目中:self.feeditems = items;

关于ios - UITableViewController : Objects properties deallocated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24099013/

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