Ios UITableViewController:解除分配的对象属性
我正在使用Ios UITableViewController:解除分配的对象属性,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我正在使用UITableViewController显示来自web服务的文章列表。检索数据后,将调用此委托方法: -(void)itemsDownloaded:(NSArray *)items { // Set the items to the array _feedItems = items; // Reload the table view [self.tableView reloadData]; } 我还使用了一个自定义单元格,这样标签的高度会发生变化,
UITableViewController
显示来自web服务的文章列表。检索数据后,将调用此委托方法:
-(void)itemsDownloaded:(NSArray *)items
{
// Set the items to the array
_feedItems = items;
// Reload the table view
[self.tableView reloadData];
}
我还使用了一个自定义单元格,这样标签的高度会发生变化,因此使用以下代码显示文章的整个标题(遵循本教程):
第一个问题是对rowatinexpath的方法调用了两次,而不是一次。因此,如果\u feeditems
有10个对象,则调用该方法20次。第二次调用该方法时,我得到了文章对象null
的两个属性(ID
和Cat\u Name
):
*** -[CFString retain]: message sent to deallocated instance 0x9c8eea0
*** -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x9c8e370
当试图显示类别名称时,会触发一个EXC\u BAD\u访问
我不确定到底是什么问题,我已尝试删除代码以改变标签的高度,以查看使用此代码是否导致此问题:
- (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次。但是这篇文章的属性ID
和Cat\u Name
仍在被取消分配中
在获取数据时,\u feeditems
中所有对象的属性都是完整的,没有任何释放。我猜它发生在cellforrowatinexpath
或forrowatinexpath
中
更新
正如@Ilya K所建议的,不从tableView:heightforrowatinexpath
调用configureCell:forrowatinexpath:
停止了调用两次的问题。我还尝试过使用feedItems的属性feedItems
。到目前为止,这是在控制器
(TableViewController.m)的@界面
中设置的:
我已将其从界面中删除,并将其添加为属性(TableViewController.h):
所有Release/Retain事件类型
都指向以下方法,connectiondFinishLoading
,当从web服务检索JSON数据并为检索到的每个文章创建Article
对象时,将使用该方法:
- (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];
}
}
-(void)连接dFinishLoading:(NSURLConnection*)连接
{
//创建一个数组来存储文章
NSMutableArray*_articles=[[NSMutableArray alloc]init];
//解析传入的JSON
n错误*错误;
//以蓝色突出显示
NSDictionary*json=[NSJSONSerialization JSONObject WithData:_downloadedDataoptions:kNilOptions error:&error];
NSArray*fetchedArr=[json objectForKey:@“结果”];
//循环浏览Json对象,创建问题对象并将它们添加到我们的问题数组中
for(int i=0;i
不过,我还是不知道出了什么问题
更新3
关于connectiondFinishLoading
的更多测试我已经删除了正在解除分配的两个属性,并且没有显示解除分配的消息。我不知道是什么原因导致这两个属性(ID
和Cat\u Name
)被解除分配,此时无法从任何位置访问这些属性。您不需要调用configureCell:ForRowatineXpath:从表视图:HeightForRowatineXpath:您应该使用大小为的Article对象确定单元格高度属性:
prototypeCell函数只创建CustomTableViewCell类型的不相关空单元格,没有必要尝试重新调整其大小
tableView:cellForRowAtIndexPath:在每次需要重新绘制tableView时调用,例如,当您滚动时。这意味着您的_feeditems数组应该被分配并保持一致,以便在实例生命周期的任何时间点使用UITableView
还要确保为_feeditems声明属性,并使用此属性分配数据
例如:
@财产(强)NSArray*饲料项目;或@property(副本)NSArray*饲料项目
在itemsDownloaded中:
self.feeditems=项目 最终解决了取消分配邮件的问题。使用Instruments
和Zombie
模板(使用Instruments
和Zombie
模板:)时,我发现这一行:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:_downloadedData options:kNilOptions error:&error];
在连接中,IDFinishLoading
方法导致此问题。我搜索了导致解除分配消息的NSJSONSerialization,从这个问题中得到了答案。文章
类有几个属性被设置为assign
,而不是strong
:
@interface Article : NSObject
@property (nonatomic, assign) NSNumber *ID; // changed assign to strong
@property (nonatomic, strong) NSString *Title;
@property (nonatomic, strong) NSString *Subtitle;
@property (nonatomic, strong) NSString *Content;
@property (nonatomic, strong) NSString *ImageUrl;
@property (nonatomic, assign) NSNumber *PostId; // changed assign to strong
@property (nonatomic, strong) NSString *Author;
@property (nonatomic, assign) NSNumber *ArticleOrder; // changed assign to strong
@property (nonatomic, assign) NSNumber *Cat_Id; // changed assign to strong
@property (nonatomic, assign) NSString *Cat_Name; // changed assign to strong
@end
将属性更改为strong
后,所有解除分配的消息都停止了
我知道这一错误似乎对每个项目都非常具体,其原因可能会有所不同,但如果有人有类似的错误,我就是这样解决的。好吧,那么
Zombie Messaged
An Objective-C message was sent to a deallocated 'CFString (immutable)' object (zombie) at address: 0x10c64def0
- (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];
}
}
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:_downloadedData options:kNilOptions error:&error];
@interface Article : NSObject
@property (nonatomic, assign) NSNumber *ID; // changed assign to strong
@property (nonatomic, strong) NSString *Title;
@property (nonatomic, strong) NSString *Subtitle;
@property (nonatomic, strong) NSString *Content;
@property (nonatomic, strong) NSString *ImageUrl;
@property (nonatomic, assign) NSNumber *PostId; // changed assign to strong
@property (nonatomic, strong) NSString *Author;
@property (nonatomic, assign) NSNumber *ArticleOrder; // changed assign to strong
@property (nonatomic, assign) NSNumber *Cat_Id; // changed assign to strong
@property (nonatomic, assign) NSString *Cat_Name; // changed assign to strong
@end