I'm converting data (from a web page) to a string). The basic code works (but there's been some subtle change somewhere - maybe on server).
NSLog shows the expected string (maybe 1000 chars long). However, when I float over responseString, it shows "Invalid". Worse, parsing with componentsSeparatedByCharactersInSet does not work.
Ideas?
NSString *responseString;
responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog([NSString stringWithFormat:#"responsestring ='%#'",responseString]);
if ([responseString compare:#""] != NSOrderedSame) {
lines = [responseString componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#";"]];
This may happen when the configuration is set to "Release" rather than "Debug" I think.
Do not trust what the debugger says, it is not accurate, this has happened to me and took me a while to realise that the xcode debugger is not always right and should not be trusted, so i no longer trust the debugger and i use nslog statements whenever it tries to tell me something is invalid. So dont worry about it it happens, and when it happened to me I was also parsing responses from some webservice.
Just to be clear -- my experience with seeing "Invalid" in the debugger means that the reference is to an already-released object.
Your question and the comments below seem to suggest that you are thinking "Invalid" is an actual string value -- but are you sure you don't just have a memory management probably?
Related
I am trying to encode a URL, I've never done this before, so I'm confused when not getting the results expected.
I'm using CFURLCreateStringByAddingPercentEscapes to do this, but whats returning looks nothing like any online URL encoders/decoders e.g.
-(void)urlEncodedString{
NSString *str = #"\"Hi!! my name is John. \n What's your's?\"";
NSLog([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)str, NULL, CFSTR("!$&'()*+,-./:;=?#_~"), kCFStringEncodingUTF8) autorelease]);
}
I was expecting something like:
%5C%22Hi%21%21%20my%20name%20is%20John.%20%5Cn%20What%27s%20your%27s%3F%5C%22
But instead I'm getting:
2i2212yame 0s2ohn3.786691E-27020A2hat º»åå2our 0.0000002
That can't be normal. I've been searching and tried everything, the way I did it apparently should work.
Can anyone point me in the right direction?
You are passing the result as the first string to NSLog which expects a string with formatting which uses the percent signs. You are essentially filling the string with random data in memory in place of each % escape. To fix this log using an Objective-C object specifier:
NSLog(#"%#", [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)str, NULL, CFSTR("!$&'()*+,-./:;=?#_~"), kCFStringEncodingUTF8) autorelease]);
Or at least I can't figure out how to locate the error. I've read a ton of stuff but every time I go into my Product scheme and turn on Guard Malloc my program won't run.
The line of code that is giving me the problem is this... It happens on the NSString *str = ... line
- (void) setVolumeCompletionDate: (NSString *)volumeID: (double)completionDate
{
sqlite3_stmt *pStmt;
NSString *str = [NSString stringWithFormat:#"UPDATE Volumes SET GoalDate = %d WHERE VolumeID = '%#'", completionDate, volumeID];
//more stuff
}
If I hardcode the completionDate value (1350129600) on that line, the code works just fine, so it seems from everything I've read that the memory of completionDate is getting stepped on somewhere, or something bad is happening. My project is set up for ARC.
I think part of my problem is I don't even know where to go to begin to resolve this problem. I don't even know what to search for. All of the posts I've read about tracking it down with some Malloc tool don't make sense because I can't get that to run.
I would like to be able to figure this out. Maybe I need more, and complete steps, for debugging and tracing through things. Many of the answers I've read seem like they are written for people who know everything, because so much is left out of the answer, or so much is assumed about the person asking the question. If there is a better place for me to go to ask my question, please point me in that direction.
Thanks a lot. I appreciate your help.
completionDate is a double, so use %f instead of %d.
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
Ok, I spent the last 8 hours fighting with it - it just seems beyond me. Here's my complete (relevant) code:
- (void)updateUserDefaults
{
NSMutableDictionary *viewControllerDetails = [[NSMutableDictionary alloc] initWithCapacity:4];
[viewControllerDetails setObject:[NSNumber numberWithInt:OOVenueClassControllerType] forKey:#"classType"];
[viewControllerDetails setObject:self.searchTerm forKey:#"searchTerm"];
[viewControllerDetails setObject:self.searchLocation forKey:#"searchLocation"];
//----- the next two lines cause the problem
NSString *res = [[NSString stringWithFormat:#"%#",[searchResults xmlString]] retain];
[viewControllerDetails setObject:res forKey:#"searchresults"];
//-----
NSMutableArray *viewControllersList = [NSMutableArray array] ;
[viewControllersList addObject:viewControllerDetails];
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
//the following line causes the error
[defs setObject:viewControllersList forKey:kViewControllersKey];
[defs synchronize];
[res release];
}
Note the block with the next two lines cause the problem. At first I didn't create another string, but added it later while trying to solve the problem.
If I comment out those two lines, everything works fine. If I put them back in, I get
- [CFString class]: message sent to deallocated instance 0xa1a9000
Is something is wrong with the string that I'm trying to put into the userdefaults? That string is rather large (about 200,000 characters), but I had stored even longer strings in user defaults in the past.
It's also worth noting that if I uninstall the app, then everything works fine. But on subsequent runs the problem exhibits itself.
So, how and why and where is the string getting deallocated? I have explicitly added retain - but that still doesn't help. What am I missing?
Edit: just realised I forgot to say that the error is thrown on line
[defs setObject:viewControllersList forKey:kViewControllersKey];
Also, for general information, method - (NSString *)xmlString on searchResults does exactly what the name means: creates an XML string with the information from that object.
Edit 2: I tried doing something else with that string - convert it to NSData, compress using zlib - but regardless of data type, that particular object gets deallocated. Does it have to do something with the size of the string?
NSString *res = [[NSString stringWithFormat:#"%#",[searchResults xmlString]] retain];
Is auto released. You don't need to release it at the end of your method. You are over-releasing it.
Further, you don't need to retain the [searchResults xmlString]. The stringWithFormat method already does it for you.
Good Luck!
Ok, not sure what exactly the problem was, but it was somewhere in the searchResults and/or xmlString method. searchResults object is originally created from XML received from the server (XML is parsed into the object structure). When xmlString was called, for some reason the string I was getting back was different from the original XML (I'm not talking about formatting, of course) - of 200,000 char-long string, within the first 500 chars or so there were some differences. I haven't been able to figure out why. So, instead of recreating the xml from object structure, I instead stored the original XML in a field in that object and, when xmlString was called, simply returned the original string. Now everything worked fine.
Thank you all for your support through this painful process.
I have UITextField of username and password, once the user hit the submit button I do
NSString* user_name;
NSString* pass_word;
UITextField * username;
UITextField * password;
NSString * url;
user_name=username.text;
pass_word=password.text;
url = [[NSString stringWithFormat:#"devices.json?user=%#&pswd=%#", user_name,pass_word];
However, when I try that, sometimes I got EXEC_BAD_ACCESS issue with url, I used the Zombie tool and nailed it %# is the one causing issue with url string. %# expecting a NSString of user_name, pass_word but somehow in the process, the user_name and pass_word got mutated and got some junk values, not NSString anymore.
I try to use [user_name retain]; [pass_word retain]; [url retain]; but didn't help. It keep having EXEC_BAD_ACCESS issue with %# parameter of the url.
secondly I able to output the user_name, pass_word, it sometimes got some values that doesn't make sense. I don't where they got those values. I didn't put those values in. I am making a http call. somehow the http returned values sneaked inside the pass_word, and user_name, I have no idea why it's doing that.
secondly I able to output the user_name, pass_word, it sometimes got some values that doesn't make sense.
this usually means that you assign not initialized variables... and it explains the crashes if you try to nslog the values. but it's not possible to find out what's wrong from the part of the code you have included in your answer.
try to log the contents of username and password. (the uitextfields) .. you should use better variable names.
From a comment:
I declare NSString *user_name, *pass_word in common.h file which many
files need to access that one.
Unless you've got a singleton class, every time you alloc/init a new Common object it's going to have trash values. Objective-C best practices recommend against this sort of design. For most data, it's fine to store in a plist or in NSUserDefaults, but for the username and password string, you should store it in the keychain. Even better, you should store your password as a hash if the server will accept it.
Then use a category on NSString (call it something like NSString+Authentication) that has methods to pull the data from the keychain as well as insert it into the keychain.
Try using the allocation as well and see if it helps:
url = [[NSString alloc] initWithFormat:#"devices.json?user=%#&pswd=%#", user_name,pass_word];
I have a strange behave:
After making a few changes in my code, I got an unasked URL in the NSURL. Actually, this URL was valid in a test I made yesterday, but the system remembers this URL and I cannot changed it even in another app.
When I strted a new app with the followung code:
int main(int argc, char *argv[]) {
NSURL *URLurl = [NSURL URLWithString:#"http://www.google.com"];
NSLog([URLurl absoluteString]);
}
the baseUrl is something like: http:inl.co.il, even I asked for google.com,
the NSLog is correct and prints: http://www.google.com
But it does not help me since the base is what the entire code works with.
And strangly, where from is that NSURL taking this old unused string?
Any help?
Thank you
Never log variables directly inside of NSLog like this, as any percent symbols will easily cause mayhem. Instead do:
NSLog(#"%#", [URLurl absoluteString]);
Lacking further information, this is probably the root of the problem. Also, the compiler should be warning you your original statement is dodgy, anyway.