對(duì)于敏感數(shù)據(jù),我們不希望長(zhǎng)時(shí)間放在內(nèi)存中,而希望使用完后立即就被釋放掉。
但是不管是 ARC 還是 MRC,自動(dòng)釋放池也有輪循工作周期,我們都無(wú)法控制內(nèi)存數(shù)據(jù)被擦除的準(zhǔn)確時(shí)間,讓 hackers 們有機(jī)可乘。 本文介紹一個(gè)小技巧——及時(shí)數(shù)據(jù)擦除。
假如一個(gè) View Controller A的一個(gè)數(shù)據(jù)被綁在一個(gè) property 上,
@interface WipingMemoryViewController : UIViewController
@property (nonatomic,copy) NSString *text;
@end
當(dāng) A push 到另外一個(gè) View Controller B 時(shí),該數(shù)據(jù)還是有可能被讀到的
WipingMemoryViewController *lastController = (WipingMemoryViewController *)self.navigationController.viewControllers[0];
NSLog(@"text = %@",lastController.text);
于是,“用后即擦”變得十分必要:
_text = [[NSString alloc]initWithFormat:@"information"];
NSLog(@"Origal string = %@",_text);
//do something...
charchar *string = (charchar *)CFStringGetCStringPtr((CFStringRef)_text, CFStringGetSystemEncoding());
memset(string, 0, [_text length]);
NSLog(@"final text = %@",_text);
Log 輸出如下:
WipingMemory[2518:70b] Origal string = information
WipingMemory[2518:70b] final text =
可以看到,我們想要保護(hù)的數(shù)據(jù),被有效的擦除了。
還有提個(gè)醒,如果是這樣
_text = @"information";
創(chuàng)建的字符串,是會(huì)被分配到 data 區(qū),而是無(wú)法修改的。
如果有興趣也有閑心,可以試試運(yùn)行下面的代碼,有彩蛋哦:
_text = @"information";
memset((__bridge voidvoid *)(_text), 0, _text.length - 1);
NSString *myString = [[NSString alloc]initWithFormat:@"information"];
NSLog(@"Origal text : %@ \n",myString);
編譯器把兩個(gè) information 的省略到一個(gè)地址了~