Monday, April 25, 2011

Why does Cocoa return an empty string occasionally?

I have some code in my application that looks something like this:

char *hash = (char*) sqlite3_column_text(get_bookmark, 0);
NSString* postHash = [NSString stringWithUTF8String:hash];

This works for me every time; I've never seen it not work. Most of my users do not experience problems (as far as I know). However I find that postHash is an empty string (@"") for some users some of the time.

Can anyone explain why?

Some more context/speculation:

This only seems to happen on jailbroken handsets. Is there anything different about them? I gather that there's usually less memory available. Anything else that could contribute here?

postHash is used in a table cell and is occasionally seen to be populated correctly so I'm reasonably confident that the database call should work. In fact, if the database also has an empty string it's because of a very similar piece of code so the question remains.

hash is certainly returning with a non-NULL value. If I force a NULL here, the app crashes. Similarly, postHash is not nil as that would also crash the app (for the same reason).

I am thinking that this is possibly memory related. If the method tries to allocate too much memory before -didReceiveMemoryWarning can get called what happens? I know that, at some point, the Springboard ejects the app. But is it possible that Cocoa returns a null string here rather than the expected value? I've heard of a few reports that, as far as I can tell, can only have been caused by an empty string being present where something longer should have been present.

Any other speculation, theories or ideas welcome.

From stackoverflow
  • However I find that postHash is an empty string (@"") for some users some of the time.

    Can anyone explain why?

    Because hash is an empty string (hash[0] == '\0').

    Stephen Darlington : I agree that this would be the most likely scenario but, as noted in the question, I'm pretty confident that it can't be an empty string.
    Peter Hosey : It's not “the most likely scenario”; it's the *only* scenario. NULL gets you an exception. Any non-empty string gets you a non-empty string. Only an empty string gets you an empty string. Simple proof: NSLog the length in (strlen(hash)) and length out ([postHash length]).
  • I finally found the solution to this. I'm going to give Peter the accepted answer as he is right but the reason that I was getting an empty string is... interesting.

    The database is populated correctly. The query is also correct. The difference between my phone and my users is that they have jail broken handsets. And apparently jail broken iPhones sometimes use a different version of SQLite than found in shipping versions of iPhone OS.

    The change in version exposed a bug in my code that caused one of the parameters to be set incorrectly and sqlite3_column_text to return an empty string.

    Max Howell : There needs to be a way to detect a jailbroken phone and then decline users support. How much time did you waste because of this? It's not on.
    Stephen Darlington : Difficult to be sure, but I think it took me about twenty hours -- and I only found the solution by accident! On the flip side, they were paying customers. Still, I have said that I reserve the right not to support jail-broken phones. I wrote more on the apps blog: http://www.yummyapp.com/2009/05/pirates-and-jail-break.html

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.