2011-04-11 29 views
0

當我使用NSString stringWithFormat構造一個動態URL,然後在我的XML解析器中使用該值時,我得到隨機崩潰。但是,如果我有一個字符串常量,它工作正常...NSString stringWithFormat導致iPhone應用程序崩潰

這是我生成的字符串代碼,

loginURL = [NSString stringWithFormat:@"%@%@",ScriptURLString,@"authenticate"]; 

導致,

http://edms.digistorm.com.au/test/index.php?s=&sc=D41D8CD98F00B204E9800998ECF8427E&m=authenticate 

然後我用它測試在我的XML解析器中,

XMLReturnData = [[NSMutableArray alloc] init]; 
xml = [[XMLParser alloc] 
     initWithXMLPath:loginURL 
     lookForElement:@"Authenticate" 
     setCallbackObject:self 
     withSelector:@selector(dataReady) 
     data:XMLReturnData 
     ]; 

由於某些原因,這導致我的應用程序崩潰。如果我使用一個字符串常量一樣,

loginURL = @"http://edms.digistorm.com.au/test/index.php?s=&sc=D41D8CD98F00B204E9800998ECF8427E&m=authenticate"; 

它工作正常...

loginURL被定義爲的NSString * loginURL;在這個視圖的頭文件裏面。

任何幫助或指導將不勝感激!

感謝, 添

+0

你能給我們提供的錯誤嗎?如果可能的話,從控制檯複製堆棧跟蹤。 – rckoenes 2011-04-11 07:57:36

+0

任何控制檯消息? – Alkimake 2011-04-11 07:57:47

回答

0

這表明你的字符串被釋放,當你在XML解析器中調用它時,它會崩潰應用程序。

實際上stringWithForma t給出了autorelease字符串的對象。

因此,您需要將您的字符串作爲保留屬性放在.h中,然後在.m中進行合成並在dealloc方法中釋放它。

,也做到這一點,

viewDidLoad

NSString *tempString=[[NSString alloc] init]; //using this because your string is retain type so it prevent increment in retain count. 
self.loginURL=tempString; 
[tempString release]; 

現在,當您使用stringWithFormat使用這樣

self.loginURL = [[NSString stringWithFormat:@"%@%@",ScriptURLString,@"authenticate"] retain]; 

它解決您的問題。

+0

這也是錯誤的。 tempString沒問題,但是每次使用保留而沒有釋放,它都會導致記事本泄漏。你還沒有定義你是如何創建你的loginURL屬性的。它是(保留)或(分配)。如果是(保留),你應該使用'self.loginURL = [NSString stringWithFormat:@「%@%@」,ScriptURLString,@「authenticate」];'。沒有保留和自我。你也可以像tempString一樣使用'[[NSString alloc] initWithFormat:@「%@%@」,ScriptURLString,@「authenticate」];' – Alkimake 2011-04-11 09:00:42

+0

@Alkimake,如果你仔細閱讀當你使用一個讓你的對象自動釋放的函數時,你也需要保留它。在屬性之前使用自己是好的一點我改變了(我總是使用自己的屬性,但是當你分配屬性時,它必須否則你可以使用沒有自己) – Ishu 2011-04-11 10:11:22

+0

我誤讀,對不起。順便說一下,如果你分配,你可以使用自我。但是你必須再次發佈。確保現有對象將在賦值之前釋放是一種很好的方法,並且在賦值後,retainCount將爲2.然後再次釋放。這是已知的內存管理方法。 – Alkimake 2011-04-11 10:26:29

0

試試這個,它可以幫助你。

loginURL = [NSString stringWithFormat:@"%@authenticate",ScriptURLString]; 
0

不叫releaseloginURL,因爲你have'nt alloced它只有iOS的有權摧毀它......

使用下面的代碼

loginURL = [[NSString alloc] initWithFormat:@"%@%@",ScriptURLString,@"authenticate"]; 

一旦你使用loginURL不要忘記打電話給release ...

[loginURL release]; 
4

用於分配字符串的方法非常重要。

你有兩個基本的辦法來分配你的字符串:

NSString *loginURL = [[NSString alloc] initWithFormat:@"%@authenticate", ScriptURLString]; 

相比:

NSString *loginURL = [NSString stringWithFormat:@"%@authenticate", ScriptURLString]; 

爲先,可可約定說,因爲你造成通過頁頭創建的對象消息「擁有」它並負責釋放它。

對於後者,約定是因爲你使對象由類的「便利」方法創建,所以你不擁有它並且不負責釋放它。這個類(這裏是NSString)具有通過autorelease池釋放的責任。

總而言之,當你使用alloc/init顯式創建某個東西時,必須釋放它。當你使用[NSThing thingWithXXX]風格的方法時,你不能。

+0

你說錯了,你說的常量字符串相當於'NSString * loginURL = [[NSString alloc] initWithFormat:@「%@ authenticate」,ScriptURLString];'。包含由自動釋放池處理並添加到自動釋放池的字符串。如果你分配字符串,它是你的責任釋放它。但對於常量字符串,您不得釋放。第二種方法創建一個由NSString類所擁有的字符串,該字符串也將其放入自動發佈池中。所以常量字符串更可能是創建了購買NSString靜態方法的字符串。 – Alkimake 2011-04-11 08:12:43

+0

@Alkimake很正確,修復了它。我的觀點實際上只是澄清他應該什麼時候應該而不應該調用release,因爲如果沒有整個代碼,我們不能確定他在做什麼,這聽起來像是他不應該發佈的時候。 – 2011-04-11 08:19:03