再次 EXC_BAD_ACCESS
我正在构建(尝试...)一个 iPhone 应用程序。 我的第一个用户故事是一个登录视图,它将用户的凭据发送到 Web 服务 (WCF)。 与网络服务的通信过程工作正常,没有任何问题。 但我必须反序列化来自它的消息。为此,我使用 NSXMLParser 创建包含服务响应的消息对象。当问题开始时:
这是消息解析器:
.h.m
@interface MessageParser : NSObject <NSXMLParserDelegate> {
NSMutableString* currentProperty;
Message* message;
}
@property (nonatomic, retain) NSMutableString* currentProperty;
@property (nonatomic, retain) Message* message;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err;
@end
那么发生
@implementation MessageParser
@synthesize message, currentProperty;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
if (err && [parser parserError]) {
*err = [parser parserError];
}
[parser release];
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if(qName){
elementName = qName;
}
if([elementName isEqualToString:@"Message"]){
self.message = [[Message alloc] init];
}
else if( [elementName isEqualToString:@"body"] || [elementName isEqualToString:@"code"] || [elementName isEqualToString:@"error"]){
currentProperty = [NSMutableString string];
}
}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if(qName){
elementName = qName;
}
if(message){
if([elementName isEqualToString:@"body"]){
self.message.messageBody = currentProperty;
}
else if([elementName isEqualToString:@"error"]){
self.message.error = currentProperty;
}
else if([elementName isEqualToString:@"code"]){
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
self.message.messageCode = [f numberFromString:currentProperty];
[f release];
}
}
self.currentProperty = nil;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)foundedCharacters
{
if (self.currentProperty) {
[currentProperty appendFormat:@"%@", foundedCharacters];
}
}
这是登录操作:
- (IBAction)didLogin:(id)sender
{
NSData* receivedData;
NSError* parserError;
NSError* error;
receivedData = [[ServiceClient PerformLogin:txtLogin.text withPassword:txtPassword.text error:error] retain];
MessageParser* messageParser = [[MessageParser alloc] init];
Message* msg;
[messageParser parseMessageData:receivedData parseError:&parserError];
msg = [messageParser.message retain];
if(msg && !msg.error){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Login Service Response" message:msg.messageBody delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(msg.error){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Error" message:msg.error delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(!msg){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Enable to contact the Athentication service." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
消息对象:
@interface Message : NSObject{
NSString* messageBody;
NSNumber* messageCode;
NSString* error;
}
@property (retain, nonatomic) NSString* messageBody;
@property (retain, nonatomic) NSNumber* messageCode;
@property (retain, nonatomic) NSString* error;
@end
@implementation Message
@synthesize error, messageBody, messageCode;
@end
了什么? 有时,当 clik 登录时,它会向我显示警报,然后 xcode 会在这段代码的 main.m 中向我抛出 EXC_BAD_ACCESS 错误:
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
而有时,当我单击登录时,它会直接向我抛出相同的错误。
我的代码有什么问题吗?我有内存管理问题吗?在哪里 ?
谢谢。
I'm building(trying ... ) an iPhone application.
My first user story is a login View who send the credential of the user to a webservice (WCF).
The communication process with the web service is working fine without any problem.
But I have to deserialize the message coming form it. For that I used the NSXMLParser to create the message Object who contain the response of the service. This when the problem begin :
This is the Message parser :
.h
@interface MessageParser : NSObject <NSXMLParserDelegate> {
NSMutableString* currentProperty;
Message* message;
}
@property (nonatomic, retain) NSMutableString* currentProperty;
@property (nonatomic, retain) Message* message;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err;
@end
.m
@implementation MessageParser
@synthesize message, currentProperty;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
if (err && [parser parserError]) {
*err = [parser parserError];
}
[parser release];
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if(qName){
elementName = qName;
}
if([elementName isEqualToString:@"Message"]){
self.message = [[Message alloc] init];
}
else if( [elementName isEqualToString:@"body"] || [elementName isEqualToString:@"code"] || [elementName isEqualToString:@"error"]){
currentProperty = [NSMutableString string];
}
}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if(qName){
elementName = qName;
}
if(message){
if([elementName isEqualToString:@"body"]){
self.message.messageBody = currentProperty;
}
else if([elementName isEqualToString:@"error"]){
self.message.error = currentProperty;
}
else if([elementName isEqualToString:@"code"]){
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
self.message.messageCode = [f numberFromString:currentProperty];
[f release];
}
}
self.currentProperty = nil;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)foundedCharacters
{
if (self.currentProperty) {
[currentProperty appendFormat:@"%@", foundedCharacters];
}
}
this is the Login action :
- (IBAction)didLogin:(id)sender
{
NSData* receivedData;
NSError* parserError;
NSError* error;
receivedData = [[ServiceClient PerformLogin:txtLogin.text withPassword:txtPassword.text error:error] retain];
MessageParser* messageParser = [[MessageParser alloc] init];
Message* msg;
[messageParser parseMessageData:receivedData parseError:&parserError];
msg = [messageParser.message retain];
if(msg && !msg.error){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Login Service Response" message:msg.messageBody delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(msg.error){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Error" message:msg.error delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(!msg){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Enable to contact the Athentication service." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
the Message Object :
@interface Message : NSObject{
NSString* messageBody;
NSNumber* messageCode;
NSString* error;
}
@property (retain, nonatomic) NSString* messageBody;
@property (retain, nonatomic) NSNumber* messageCode;
@property (retain, nonatomic) NSString* error;
@end
@implementation Message
@synthesize error, messageBody, messageCode;
@end
So what is happened ?
Some time when is clik login it show me the alert then xcode throw me EXC_BAD_ACCESS error in the main.m in this code :
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
And some time when I click login it throw me the same error directly.
What's wrong with my code ? Do I have some memory management problems ? where ?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在使用一种方便的方法而不保留结果....
要么做...
要么在使用保留属性声明属性时看到使用...
另请注意,以下行正在泄漏内存....
作为属性还有一个保留属性,您需要发布您创建的版本...
...或者...
You are using a convenience method without retaining the result....
either do...
or seeing as you declare the property with a retain attribute use...
Also note that the following line is leaking memory....
as the property also has a retain attribute you need to release the version you create...
...or...
将
NSZombieEnabled : YES
放入项目的“编辑活动可执行文件”部分。我希望它可以帮助追踪这个问题。put
NSZombieEnabled : YES
in your project's "Edit Active Executable" section. I hope it could help to get a trace on the issue.