IOS使用CFURLCreateStringByAddingPercentEscapes進行URL編碼
iOS程式訪問HTTP資源時需要對URL進行UTF8編碼,我在之前一直都喜歡使用NSString的stringByAddingPercentEscapesUsingEncoding方法進行編碼。今天在使用Analyze分析工程時,提示下面的方法可能存在記憶體泄露:
NSString *enString =(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)stringURL, NULL, NULL, kCFStringEncodingUTF8);
注意到這個方法也是一個編碼方案,就查詢了兩種方式的區別,有些收穫。額外學習UITabBarController隱藏tabBar以及addChildViewController
stringByAddingPercentEscapesUsingEncoding方法有一個問題:不會轉轉URL中的”%&?”等符號[這個很好理解,因為不好區分這些特殊字元到底是串連符號還是參數值]。這些字元在URL文法中有特殊的含義,如果在URL的參數中有這些字元,就需要轉化為”%+ASCII”的形式。如果參數中存在這些字元,而我們又使用了stringByAddingPercentEscapesUsingEncoding方法,則伺服器會將參數中的沒有轉義的&當做分隔字元,造成分析錯誤。因為我的工程中幾乎沒有在參數中存在%&等符號的情況,所以一直用也沒問題。但咱們還是要使用正規的方式。
一般來說都是用:
CFStringRef CFURLCreateStringByAddingPercentEscapes( CFAllocatorRef allocator, CFStringRef originalString, /*待轉碼的類型*/ CFStringRef charactersToLeaveUnescaped, /*指示不轉義的字元*/ CFStringRef legalURLCharactersToBeEscaped,/*指示確定轉義的字元*/ CFStringEncoding encoding); /*編碼類別型*/
| 123456 |
CFStringRefCFURLCreateStringByAddingPercentEscapes( CFAllocatorRef allocator, CFStringReforiginalString,/*待轉碼的類型*/ CFStringRef charactersToLeaveUnescaped,/*指示不轉義的字元*/ CFStringReflegalURLCharactersToBeEscaped,/*指示確定轉義的字元*/ CFStringEncoding encoding);/*編碼類別型*/ |
方案就是單獨編碼參數值(如果編碼整個URL的話會講URL分割符&等也編碼),最後拼接成完整的字串。
樣本Demo如下:
CFStringRef escaped = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8); NSString *out = [NSString stringWithString:(NSString *)escaped]; CFRelease(escaped);//記得釋放
| 123 |
CFStringRefescaped =CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8); NSString *out= [NSStringstringWithString:(NSString *)escaped]; CFRelease(escaped);//記得釋放 |
另外一個小知識點:
在之前做圖片切割時經常用到如下代碼
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
| 12 |
CGImageRefnewImageRef =CGImageCreateWithImageInRect(sourceImageRef,rect); UIImage *newImage= [UIImageimageWithCGImage:newImageRef]; |
實際上這個代碼會造成記憶體泄露,正確的方式是還需要釋放newImageRef,如下:
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; CGImageRelease(newImageRef);
| 123 |
CGImageRefnewImageRef =CGImageCreateWithImageInRect(sourceImageRef,rect); UIImage *newImage= [UIImageimageWithCGImage:newImageRef]; CGImageRelease(newImageRef); |