views:

802

answers:

2

I have some sensitive data I want to clear directly after use. Currently, the sensitive data is in the form of NSString. NSString is in my understanding immutable, meaning that I can't really clear the data. NSMutableString seems more appropriate, though, as it is mutable and has methods like replaceCharactersInRange and deleteCharactersInRange. I have no knowledge of the implementation details so I wonder if NSMutableString would serve my purpose?

A: 

Hi, there is a hell lot of difference between nsstring and nsmtablestring. And always keep practice of using nsmutablestring when you are going to change the content of string.

ex:

NSString *aString = [nsstring stringWithString:@"asdasd"]; // autoreleased object

here you have created a string and want to add other string, then you will do:

astring = [astring stringByAppendingString:@"asdasd"]; //autoreleased object

here what happens is new autoreleased string is returned and the previous string is not get released. This will lead to memory leak(consumption) because you have lost the ownership of the first autoreleased object.

Think if you are using the second statement in a loop:

for(int i=0 ; i<1000 ; i++)
    astring = [astring stringByAppendingString:@"asdasd"]; //autoreleased object

Then you are leaking the memory even though you cant see it.

If you used NSMutableString instead of NSString then you never come across this type of situation and you can avoid the leak and as well as autoreleased objects :)

like:

    NSMutableString *aString = [[NSMutableString alloc] initWithString:@"asdasd"];
    for(int i=0; i<1000 ; i++)
        [aString appendString:@"asdasd"];

    [aString release];
    aString = nil;

This is the main difference b/n Mutable and immutable String:

  1. Avoids Autoreleased objects.

  2. Avoids Memory surge.

  3. Cleaning memory is easier and efficient.

Manjunath
Note that even you have placed the comment "autoreleased object" after those lines of code. There is no leaking there. Using an autoreleased object within a loop is perfectly fine. It may not be the as efficient as your second example, but it doesn't leak - it just won't be freed until the end of the run loop. Check facts before posting please. Also, this has nothing to do with the original question.
Jasarien
...so how do you suggest I would wipe out the sensitive data? There must be some way to overwrite the contents with zero or some other garbage when finished using the data.
AOO
@Jasarien: "Check facts before posting please." I don't post something without any experience. Just tryout the code and check the performance of your application. And you said, "but it doesn't leak - it just won't be freed until the end of the run loop" could you please tell me what is the Run loop? When it will end? and if you dont have the ownership of an object then how will you release that object?
Manjunath
If an object is autoreleased, it will be released at the end of the run loop and unless you retain an autoreleased object before the end of the run loop, it will be deallocated, because it's retain count will reach 0. This is a basic memory management concept that is prevalent throughout the Cocoa and Cocoa Touch frameworks. The memory is not leaked when using autoreleased objects, unless you retain them and don't explicitly release them yourself. That is the whole point of autorelease. Read: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
Jasarien
For run loop information, see here: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1
Jasarien
I know what exactly Autorelease and Run loop are. But tell me is it a good practice of using Autoreleased objects more and in such a limited memory devices?And I asked you one more question regarding performance of an application if you use Nsstring autoreleased objects.
Manjunath
Please dont mistake me :) I want you to just check out whether NSString Objects gets released after the completion of Runloop. You can try it out in Desktop only so that you will be having large amount of memory. Just try it and reply me :)
Manjunath
You clearly don't know "exactly" what these mechanisms are... `stringByAppendingString:` returns an **autoreleased object**. You do not own these objects unless you retain them. The fact that they are autoreleased means they are added to an autorelease pool which is emptied at the end of the run loop. Emptying an autorelease pool sends a release message to all the objects within the pool. Since you don't own them because you didn't retain them, they are deallocated and the memory is freed. I agree that is isn't as efficient in a memory restricted device, but saying that it leaks is incorrect!
Jasarien
Furthermore, this discussion has nothing to do with the question at hand, so I am reluctant to continue it. There is plenty of material in the documentation to cover this topic.
Jasarien
Using stringByAppendingString in tight loops are not recommended, instead use NSMutableString.
Raj
./sigh - I *know* it's not recommended, and I *know* it is ineffecient, but it **does not leak**. Saying that it causes memory leaks is simply and plainly incorrect.
Jasarien
+1  A: 

I would be afraid NSMutableString would try to optimize and leave the string in memory. If you want more control try allocating your own memory then create an NSString with it. If you do that you can overwrite the memory before you release it.

char* block = malloc(200);
NSString* string = [[NSString alloc] initWithBytesNoCopy:length:encoding:freeWhenDone];
//use string
memset(block, 0, 200);// overwrite block with 0
[string release];
free(block);
Hua-Ying
Thanks, this was exactly what I was asking for!
AOO
`NSString` may create additional copies of the buffer passed in for its own purposes. Example: calling `-[NSString UTF8String]` will create an additional internal copy that gets released but not cleared when the `NSString` does. If you want to be guaranteed that the sensitive data is cleaned up, do *NOT* use `NSString`.
rpetrich