再次 EXC_BAD_ACCESS

发布于 2024-12-21 11:29:44 字数 4565 浏览 3 评论 0原文

我正在构建(尝试...)一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酷遇一生 2024-12-28 11:29:44

您正在使用一种方便的方法而不保留结果....

currentProperty = [NSMutableString string];

要么做...

currentProperty = [[NSMutableString string] retain];

要么在使用保留属性声明属性时看到使用...

self.currentProperty = [NSMutableString string];

另请注意,以下行正在泄漏内存....

self.message = [[Message alloc] init];

作为属性还有一个保留属性,您需要发布您创建的版本...

Message *aMessage = [[Message alloc] init];
self.message = aMessage;
[aMessage release];

...或者...

message = [[Message alloc] init];

You are using a convenience method without retaining the result....

currentProperty = [NSMutableString string];

either do...

currentProperty = [[NSMutableString string] retain];

or seeing as you declare the property with a retain attribute use...

self.currentProperty = [NSMutableString string];

Also note that the following line is leaking memory....

self.message = [[Message alloc] init];

as the property also has a retain attribute you need to release the version you create...

Message *aMessage = [[Message alloc] init];
self.message = aMessage;
[aMessage release];

...or...

message = [[Message alloc] init];
揽清风入怀 2024-12-28 11:29:44

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文