jump to navigation

NSData Naughtiness 13 July 2009

Posted by Oliver Mason in Apple, objective-c, programming.
add a comment

Well, this is not exactly NSData’s fault, but I ran into a problem (for the second time; the first time I bypassed it with a short-cut) when reading text data from a file.

Occasionally there was random garbage at the end of a line, which I could not understand. Incidentally, I was reading a number of full files in one go each into an NSData instance, and converted that into an NSString with the correct encoding; this I would then tokenise and add to another file. So the garbage was actually at the end of each file. I then found that I can directly initialise an NSString with the contents of a file, and the problem disappeared.

Now I want to produce concordance lines, and I jump into the middle of the file to read a stretch. First I run into trouble with the encoding: as the data is UTF8-encoded, a random jump can end up in the middle of a multi-byte character. NSString does not like that… but here I can just test for that and skip the initial bytes. The same problem obviously also happens at the end, where the final multi-byte character could be incomplete. Again, truncation seems the easy way out.

But I also then had the issue with the occasional random garbage again! NSData seems to be at fault, and this time I can’t bypass it, as NSString can only read a full file. Quick websearch, and the solution crops up (in an aside) on stackoverflow.com: the data that NSData returns from the -bytes method is not zero-terminated, but NSString’s -stringWithUTF8String expects that, hence the random garbage of the unterminated data. In a way I’m surprised that it actually worked most of the time!

Advertisements

Dictionary Dangers 9 July 2009

Posted by Oliver Mason in Apple, objective-c, programming.
add a comment

I just spotted a bug that cost me several hours yesterday, without having a clue what was going on. I’m currently working on a program which indexes texts, and as I encounter words, I add them to a NSMutableDictionary with their positions in the text. All was working well, until I tested it on a bunch of texts, and it failed with some obscure message about key-value coding. I then added some NSLog messages, and discovered that the token it failed on was the at sign, @.

Today I had another look at the documentation of NSMutableDictionary, and especially the method valueForKey: where the problem seemed to occur. And there it was: “If key does not start with “@”, invokes objectForKey:. If key does start with “@”, strips the “@” and invokes [super valueForKey:] with the rest of the key.” Suddenly it dawned on me: I was using the wrong method. Instead of valueForKey: I should have used objectForKey: – the plain @-sign is discarded, and leaves an empty key (which did of course make the error message less comprehensible, as I couldn’t really tell it was empty).

Quick change in the code, and it works. Problem solved!

Lesson learned: always pay close attention to the available methods, and make sure it is the one you want, even if the one you’re using sounds like it’s the right one. And read the docs carefully!