2011-07-18 162 views
0

我正在使用TouchXML來解析iOS中的元素。我使用NSInvocationOperation從Web服務中檢索響應,然後解析並顯示結果。一切使用[self performSelectorOnMainThread:@selector(displayLoginresult:) withObject:res waitUntilDone:NO];工作正常,主線程在後臺線程上顯示的結果,但後來我得到一個錯誤:我的發送到釋放實例的消息

-(LoginResult *) tryLogin:(NSString *)userName withPassword:(NSString*)password{ 
    NSURL *url = [UrlUtility TryLogin:userName passwordHash:password]; 
    CXMLDocument *responseObj = [UrlUtility xmlDocWithUrl:url]; 
    if(responseObj == [NSNull null]) 
     return [NSNull null]; 

    CXMLElement *eleUser = [responseObj nodeForXPath:@"//User" error:nil]; 
    CXMLElement *eleResult = [responseObj nodeForXPath:@"//Result" error:nil]; 
    LoginResultType resultType; 
    //NSLog(@"Result: "); 
    //NSLog(eleResult); 
// NSLog([[eleResult stringValue] lowercaseString]); 
    if ([[[eleResult stringValue] lowercaseString ] isEqualToString: @"successful"]){ 
     resultType = Successful; 
    } else { 
     resultType = InvalidUsernameOrPassword; 
    } 

    LoginResult *res = [[LoginResult alloc] init]; 
    res.result = resultType; 

    for (CXMLElement *resultElement in [responseObj children]) { 
     NSLog([NSString stringWithFormat:@"%@ %@", [resultElement name], [resultElement stringValue]]); 
    } 

    //todo: fix enum parsing =[LoginResult loginResultTypeStringToEnum: [eleResult stringValue]]; 

    if(eleUser != nil) { 
     CXMLElement *eleClientID = [eleUser nodeForXPath:@"ClientID" error:nil]; 
     CXMLElement *eleCompanyName = [eleUser nodeForXPath:@"CompanyName" error:nil]; 
     CXMLElement *eleCompanyContact = [eleUser nodeForXPath:@"CompanyContact" error:nil]; 
     CXMLElement *eleIsAgent = [eleUser nodeForXPath:@"IsAgent" error:nil]; 
     CXMLElement *eleParentID = [eleUser nodeForXPath:@"ParentID" error:nil]; 

     NSInteger *clientId = [[eleClientID stringValue] integerValue]; 
     NSString *companyName = [eleCompanyName stringValue]; 
     NSString *companyContact = [eleCompanyContact stringValue]; 
     bool isAgent = [Utils stringToBool:[eleIsAgent stringValue]]; 
     NSInteger *parentId = [[eleParentID stringValue] integerValue]; 
     User *user = [[User alloc] initWithData:clientId companyName:companyName companyContact:companyContact isAgent:isAgent parentId:parentId]; 
     res.user = user; 
     // release elements 

//  [eleClientID release]; 
//  [eleCompanyName release]; 
//  [eleCompanyContact release]; 
//  [eleIsAgent release]; 
//  [eleParentID release]; 

     //release raw values 
//  [companyName release]; 
//  [companyContact release]; 
    } 

// [eleResult release]; 
// [eleUser release]; 

    return res; 
} 

部分想了想說:

2011-07-18 11:58:06.108 billsApp[873:7107] *** -[CFString release]: message sent to deallocated instance 0x5d809b0 

解析的元素是代碼這是TouchXML的一個錯誤,但我覺得不太可能。有什麼方法可以進一步追蹤錯誤嗎?

編輯:有關用戶類屬性的定義是:

@property (nonatomic, readwrite) NSInteger clientId; 
@property (nonatomic, retain) NSString *companyName; 
@property (nonatomic, retain) NSString *companyContact; 
@property (nonatomic, readwrite) bool isAgent; 
@property (nonatomic, readwrite) NSInteger parentId; 

而且實例初始化:

-(User*)initWithData:(NSInteger *)clientId companyName:(NSString *)company companyContact:(NSString*)contact isAgent:(bool)agent parentId:(NSInteger*)parentId { 
    //[self = super init]; 
    self.clientId= clientId; 
    self.companyName= company; 
    self.companyContact= contact; 
    self.isAgent = agent; 
    self.parentId = parentId; 
    return self; 
} 

而且LoginResult類:

@interface LoginResult : NSObject { 
    LoginResultType result; 
    User *user; 

    NSString * const loginResultTypeArray[4]; 
} 

@property (nonatomic, readwrite) LoginResultType result; 
@property (nonatomic, retain) User *user; 
+0

您試圖釋放已被釋放的字符串... – Maulik

+0

我知道,但我無法看到代碼中發生或可能被觸發的位置。 – Echilon

+0

設置一個斷點在第一行的功能,並通過一步一步走.. – Maulik

回答

0

只是一個嘗試:你是否正確保留companyName和在你的User類中有嗎?

編輯:

我會檢查接下來的事情是loginResultTypeArray。字符串是如何分配給它的?我想,這個建議也將聽起來微不足道給你,但它是真的很難拿出這麼少的代碼有用的建議...

你能不能得到一些想法有關CFString實際上被釋放?如果它不是一個自動釋放的對象,可能是堆棧跟蹤可能在這一點,正在發送release消息...這將是非常有益的方法...

否則,我會嘗試和NSLog你的一些NSString S的地址,以便您可以將它們與您在錯誤日誌中找到的地址進行比較(並再次嘗試找出釋放後實際重用的字符串)。

最後,另一種方法找出哪些字符串可以使用方法混寫與你的方法,調用攪和dealloc之前,莫非objec的一些記錄,以取代NSStringdealloc刪除後使用。這會產生大量的日誌信息,但知道字符串的地址可以輕鬆找到所需的信息。查找here關於swizzling的信息。

+0

我相信是這樣,我已經將類定義添加到帖子中。 – Echilon

+1

你在''用戶''initWithData'方法中做'self.companyName = ...'嗎? – sergio

+0

是的,我。感謝您的幫助。 :)我已經將構造函數添加到OP。 – Echilon

0

這是追查的噩夢。我有一個返回NSString *的方法,然後通過另一種方法解析該方法以生成XML文檔,然後通過第二種方法發佈。我實際上需要在第一種方法中自動釋放它。

相關問題