Tam*_*Tam 2 iphone objective-c
我无法使用此代码填充previewData NSMutableArray.XML请求已成功检索,解析但我无法填充tableviewController的previewData数组.
PreviewsController.h代码:
#import <UIKit/UIKit.h>
@interface PreviewsController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
UITableView *previewList;
NSString *enteredUsername;
NSString *enteredPassword;
NSMutableString *current_xml_element;
NSMutableString *current_xml_value;
NSMutableDictionary *item;
NSMutableArray *previewData;
}
@property (nonatomic, retain) IBOutlet UITableView *previewList;
@property (nonatomic, retain) NSString *enteredUsername;
@property (nonatomic, retain) NSString *enteredPassword;
@property (nonatomic, retain) NSMutableString *current_xml_element;
@property (nonatomic, retain) NSMutableString *current_xml_value;
@property (nonatomic, retain) NSMutableArray *previewData;
@property (nonatomic, retain) NSMutableDictionary *item;
@end
Run Code Online (Sandbox Code Playgroud)
PreviewsController.m代码:
#import "PreviewsController.h"
@implementation PreviewsController
@synthesize previewList;
@synthesize enteredUsername, enteredPassword;
@synthesize current_xml_element, previewData, item, current_xml_value;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.previewData = nil;
[super viewDidUnload];
}
- (void)dealloc {
[item release];
[previewData release];
[enteredUsername release];
[enteredPassword release];
[current_xml_element release];
[super dealloc];
}
- (void)viewDidLoad {
previewData = [[NSMutableArray alloc] init];
// Fetch the XML output from API - Start
NSString *APIURL = [[NSString alloc] initWithFormat:@"http://mysite.com/api/%@/%@", enteredUsername, enteredPassword];
NSURL *url = [[NSURL alloc] initWithString:APIURL];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[APIURL release];
[url release];
[xmlParser setDelegate:self];
[xmlParser parse];
// Fetch the XML output from API - End
[super viewDidLoad];
}
#pragma mark -
#pragma mark XML Request Methods
-(void)parserDidStartDocument:(NSXMLParser *)parser {
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
current_xml_element = [elementName copy];
if ([elementName isEqualToString:@"subject"]) {
item = [[[NSMutableDictionary alloc] init] autorelease];
current_xml_value = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([current_xml_element isEqualToString:@"subject"]) {
[current_xml_value appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"subject"]) {
[item setObject:current_xml_value forKey:@"subject"];
[previewData addObject:[item copy]];
// NSLog(@"array count: %@", [previewData count]);
}
}
-(void)parserDidEndDocument:(NSXMLParser *)parser {
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(@"Error occurred: %d - %@", [parseError code], [parseError localizedDescription]);
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [previewData count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [previewData objectAtIndex:row];
return cell;
}
@end
Run Code Online (Sandbox Code Playgroud)
当我构建并运行此代码时,在控制台中返回以下错误:
2009-10-15 23:13:55.296 PreviewMyEmail[29964:207] *** -[NSCFDictionary isEqualToString:]: unrecognized selector sent to instance 0x3839a60
2009-10-15 23:13:55.298 PreviewMyEmail[29964:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary isEqualToString:]: unrecognized selector sent to instance 0x3839a60'
2009-10-15 23:13:55.298 PreviewMyEmail[29964:207] Stack: (
29307995,
2531364681,
29689915,
29259382,
29112002,
3812419,
13553,
3063392,
3029655,
3106211,
3070291,
55820976,
55820399,
55818438,
55817530,
55851064,
29094482,
29091423,
29088840,
37398413,
37398610,
2781187,
8436,
8290
)
Run Code Online (Sandbox Code Playgroud)
我哪里做错了?感谢你的帮助.
干杯.
previewData是否正在其他地方初始化?在给定代码和输出的情况下,它看起来像它没有值.[previewData count]将返回nil,这是0.添加previewData = [[NSMutableArray alloc] init];在开头,它应该工作.
可能会生成错误-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath,尤其是行:
cell.textLabel.text = [previewData objectAtIndex:row];
Run Code Online (Sandbox Code Playgroud)
在这里,您将NSMutableDictionary分配给类型为NSString的属性.应用程序的开发版本应该显示堆栈跟踪中的方法名称和行号.
由于NS集合类保留了对象,因此item除非需要不可变对象,否则不需要存储副本而不是原始副本.
如果存在多个"subject"元素,则一些复制的对象将产生内存泄漏.您可以自己处理版本或使用属性.属性更容易处理,因此更不容易出错.如果您不打算使用它们,为什么还要定义属性呢?某些属性不是公共接口的一部分,并且该类看起来不适用于库.如果您希望自己释放句柄,请记住在一个方法中使用自动/释放来平衡alloc/copy/retain.对于解析器:didStartElement:...,相应的方法是解析器:didEndElement:...我仍然试图制定一种描述这种平衡的简洁方法(即将推出到你附近的SO问题).
current_xml_element每次解析器进入一个孩子时都会被破坏.相反,您可以在开始/结束处理"主题"节点时设置/取消设置标志.这将打破,如果一个"主题"节点以往任何时候都包含一个子"主题"节点,但这样的XML文档是病态并导致其他问题(例如重挫item和current_xml_value,从而导致内存泄漏).标志的替代方法是存储一堆元素,在didStartElement期间推送并在didEndElement期间弹出.
PreviewsController.h:
@interface PreviewsController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
...
/* NSMutableString *current_xml_element; */
BOOL current_element_is_subject;
...
}
...
/* @property (nonatomic, retain) NSMutableString *current_xml_element; */
@property (nonatomic, assign) BOOL current_element_is_subject;
...
@end
Run Code Online (Sandbox Code Playgroud)
PreviewsController.m
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"subject"]) {
self.item = [NSMutableDictionary dictionaryWithCapacity:1];
self.current_xml_value = [NSMutableString stringWithCapacity:80];
current_element_is_subject = YES;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (current_element_is_subject) {
[current_xml_value appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"subject"]) {
[item setObject:current_xml_value forKey:@"subject"];
[previewData addObject:item];
current_element_is_subject = NO;
// NSLog(@"array count: %@", [previewData count]);
}
}
Run Code Online (Sandbox Code Playgroud)
博客文章" 让NSXMLParser成为你的朋友 "看起来基本上和你想做的一样.研究它可能会有所帮助.