Objective-C:Foundation框架-常用類-NSString全解


  Foundation框架中常用的類有字符串、集合、字典等,這里介紹字符串NSString。本文分別介紹了NSString的創建、從文件里讀取NSString字符串、通過函數改變外部的NSString變量的值、NSString字符串的導出、NSString的常用方法等5個部分。

1.NSString的創建:

#pragma mark NSString的創建
void stringCreate() {
    // char *s = "A String!"; // C語言中的字符串
    
    // 這種方式創建出來的字符串是不需要釋放的
    NSString *str1 = @"A String!";
    
    NSString *str2 = [[NSString alloc] init];
    str2 = @"A String!";
    [str2 release];
    
    NSString *str3 = [[NSString alloc] initWithString:@"A String!"];
    [str3 release];
    // 不需要管理內存
    str3 = [NSString stringWithString:@"A String!"];
    
    NSString *str4 = [[NSString alloc] initWithUTF8String:"A String!"];
    [str4 release];
    str4 = [NSString stringWithUTF8String:"A String!"];
    
    NSString *str5 = [[NSString alloc] initWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];//(圖1)
    
    // 這句代碼放在中間會造成2個錯誤:
    // 1.前面創建的字符串沒有被釋放
    // 2.后面創建的字符串會釋放過度,造成野指針錯誤
    // str5 = [NSString stringWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];//(圖2、3)
    
    NSLog(@"str5:%@", str5);
    [str5 release];
    
    str5 = [NSString stringWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];
}

         

                      

                               (圖1)                                                        (圖2)                                                           (圖3)

  野指針的產生:通過“[[NSString alloc] initWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];”(動態創建)這句創建的對象是需要手動釋放內存的,如果在還沒有手動釋放之前又通過靜態方法“str5 = [NSString stringWithFormat:@"My age is %i and height is %.2f", 19, 1.55f];”(靜態創建)給str5對象賦值,那么str5將指向新的一塊內存,而原來的那塊內存沒有對象指向它了,但是也沒有被釋放,就成了野指針。動態方式創建一般都有對應的靜態方法創建。

2.從文件里讀取NSString字符串

void stringCreate2() {
    // 從文件中讀取文本
    NSString *path = @"/Users/apple/Desktop/test.txt";
    // 這個方法已經過期,不能解析中文
    // NSString *str1 = [NSString stringWithContentsOfFile:path];
    
    // 定義一個NSError變量
    NSError *error;
    // 指定字符串編碼為UTF-8: NSUTF8StringEncoding
    NSString *str1 = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    //最后的一個參數不能傳error,一定要傳error的地址,它是指向error這個指針的指針
    if (error == nil) { // 沒有錯誤信息
        NSLog(@"讀取文件成功:%@", str1);
    } else {
        NSLog(@"讀取文件失敗:%@", error);
    }
    
    NSURL *url = [NSURL URLWithString:@"file:///Users/apple/Desktop/test.txt"];
    NSString *str2 = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@", str2);
    
    NSURL *url2 = [NSURL URLWithString:@"http://www.baidu.com"];
    NSString *str3 = [NSString stringWithContentsOfURL:url2 encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@", str3);
}

3.通過函數改變外部的NSString變量的值

先看一種情況:

void test(NSString *str){
str = @"123";
}

int main(int argc, const char *argv[])
{
    autoreleasepool{
        NSString *s = @"456";
        test(s);
        NSLog(@"%@", s);
    }
    return 0;
}

  運行結果為:456。s的值並沒有改變,分析如下:

  指針變量s起初指向456(圖1),當調用test函數時,傳入參數s,函數會開辟一塊存儲空間存儲指針變量str,指針變量是存儲地址的,參數s將其存儲的地址賦值給str(值傳遞)(圖2),因此str存儲的地址也指向了456這個對象,“str = @"123";”執行后,系統又開辟了一塊存儲空間存儲123,接着讓str指向這個對象(圖3)。而s的值根本沒有變,它一直都指向456。所以,對於一個函數,如果只是把一個指針傳進去,外面的值是不會變的。

                             (圖1)                                                         (圖2)                                                                 (圖3)  

  若要通過函數改變外面指針指向的值,需要用到指針的指針,也就是把外面指針的地址傳進去。

void test(NSString **str) {
    *str = @"123";
    // s = @"123";
}
int main(int argc, const char *argv[])
{
    autoreleasepool{
        NSString *s = @"456"; test(&s); NSLog(@"%@", s); } return 0; }

  指針變量是這樣的,那對於一般類型的變量呢?看下面的例子:

void test2(int p){
    p = 9;
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        int a = 10;
        test2(a);
        NSLog(@"%i", a);
    }
    return 0;
}

  運行結果:10;

void test2(int *p) {
   *p = 9;
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        int a = 10;
        test2(&a);
        NSLog(@"%i", a);
    }
    return 0;
}

  運行結果:9。

  效果是一樣的。再次說明,如果要設計一個方法,改變外面傳進來的參數,那應該將外面這個參數的地址傳遞給函數。

4.NSString字符串的導出

#pragma mark 字符串的導出
void stringExport() {
    NSString *str = @"123456我是字符串!!!!";
    // 如果文件不存在,會自動創建文件
    // 如果文件夾不存在,會直接報錯
    NSString *path = @"/Users/apple/Desktop/abc.txt";
    
    NSError *error;
    // 編碼指定錯誤也會報錯
    // YES代表要進行原子性操作,也就是會創建一個中間的臨時文件
    [str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if (error) {
        // [error localizedDescription]會返回主要的錯誤信息
        NSLog(@"寫入失敗:%@", [error localizedDescription]);
    } else {
        NSLog(@"寫入成功");
    }
}

原子性與非原子性的區別:

  若寫入文件為原子性操作,則在寫入內容之前會創建一個臨時文件,先將內容寫入臨時文件,待內容完好無損地寫入臨時文件后,再將臨時文件里的內容移到目標文件中,中途如果出錯,臨時文件出問題,不會影響到目標文件;非原子性操作直接將內容寫入目標文件,一旦中途出錯,可能造成目標文件里只有部分內容傳入的情況。

5.NSString的常用方法

  1 #pragma mark 字符串的大小寫處理
  2 void caseTest() {
  3     NSString *str = @"GuangDong";
  4     // 轉成大寫
  5     NSLog(@"大寫:%@", [str uppercaseString]);
  6     // 轉成小寫
  7     NSLog(@"小寫:%@", [str lowercaseString]);
  8     // 首字母變大寫,其他字母變小寫
  9     NSLog(@"首字母變大寫:%@", [@"aGE" capitalizedString]);
 10 }
 11 
 12 #pragma mark 字符串的比較
 13 void compare() {
 14     // 檢測字符串的內容是否相同
 15     BOOL result = [@"abc" isEqualToString:@"abc"];
 16     NSLog(@"%i", result);
 17     
 18     // NSOrderedAscending  右邊的字符串比左邊大
 19     // NSOrderedSame  兩個字符串的內容相同
 20     // NSOrderedDescending  左邊的字符串比右邊的大
 21     NSComparisonResult result2 = [@"abc" compare:@"Abc"];
 22     if (result2 == NSOrderedSame) {
 23         NSLog(@"兩個字符串的內容相同");
 24     } else if (result2 == NSOrderedAscending) {
 25         NSLog(@"右邊 > 左邊");
 26     } else if (result2 == NSOrderedDescending) {
 27         NSLog(@"右邊 < 左邊");
 28     }
 29 }
 30 
 31 #pragma mark 字符串的搜索
 32 void search() {
 33     NSString *str = @"123456456.txt";
 34     
 35     NSLog(@"是否以22開頭:%i", [str hasPrefix:@"22"]);
 36     NSLog(@"是否以txt結尾:%i", [str hasSuffix:@"txt"]);
 37     
 38     // 搜索字符串
 39     NSRange range = [str rangeOfString:@"456"];
 40     // range.length == 0
 41     if (range.location == NSNotFound) {
 42         NSLog(@"不能找到");
 43     } else {
 44         NSLog(@"找到的范圍是:%@", NSStringFromRange(range));
 45     }
 46     
 47     // 從尾部開始搜索字符串
 48     range = [str rangeOfString:@"456" options:NSBackwardsSearch];
 49     NSLog(@"%@", NSStringFromRange(range));
 50     
 51     // 指定范圍進行搜索
 52     // [str rangeOfString:@"456" options:NSBackwardsSearch range:<#(NSRange)#>];
 53 }
 54 
 55 #pragma mark 字符串的截取
 56 void subString() {
 57     NSString *str = @"123456";
 58     
 59     // 從索引3開始截取到尾部(包括3)
 60     NSLog(@"%@", [str substringFromIndex:3]);
 61     
 62     // 從頭部開始截取到索引3之前(不包括3)
 63     NSLog(@"%@", [str substringToIndex:3]);
 64     
 65     // 指定范圍進行截取
 66     NSRange range = NSMakeRange(2, 3);
 67     NSLog(@"%@", [str substringWithRange:range]);
 68     
 69     NSString *str2 = @"a-b-c-d-5";
 70     NSArray *array = [str2 componentsSeparatedByString:@"-"];
 71     NSLog(@"%@", array);
 72     
 73     NSString *str3 =  [array objectAtIndex:0];
 74     NSLog(@"%@", str3);
 75 }
 76 
 77 #pragma mark 與路徑相關
 78 void pathTest() {
 79     // 快速創建一個自動釋放的數組
 80     NSMutableArray *components = [NSMutableArray array];
 81     [components addObject:@"Users"];
 82     [components addObject:@"MJ"];
 83     [components addObject:@"Desktop"];
 84     // 將數組中的所有字符串拼接成一個路徑
 85     NSString *path = [NSString pathWithComponents:components];
 86     NSLog(@"%@", path);
 87     
 88     // 將路徑分解成一個數組
 89     NSArray *cmps = [path pathComponents];
 90     NSLog(@"%@", cmps);
 91     
 92     // path是一個字符串常量,是不可變的
 93     path = @"/users/mj/test";
 94     // 判斷是夠為絕對路徑(依據是前面有無/)
 95     NSLog(@"%i", [path isAbsolutePath]);
 96     NSLog(@"最后一個目錄:%@", [path lastPathComponent]);
 97     // 刪除最后一個目錄
 98     NSLog(@"%@", [path stringByDeletingLastPathComponent]);
 99     // 在最后面拼接一個目錄
100     NSLog(@"%@", [path stringByAppendingPathComponent:@"abc"]);
101 }
102 
103 #pragma mark 拓展名處理
104 void extension() {
105     NSString *str = @"/User/MJ/test.txt";
106     
107     NSLog(@"拓展名:%@", [str pathExtension]);
108     // 刪除拓展名
109     NSLog(@"%@", [str stringByDeletingPathExtension]);
110     // 添加拓展名
111     NSLog(@"%@", [@"abc" stringByAppendingPathExtension:@"mp3"]);
112 }
113 
114 #pragma mark 其他用法
115 void other() {
116     NSString *str = @"12";
117     int a = [str intValue];
118     NSLog(@"%i", a);
119     
120     // 計算字數,不是計算字符數
121     NSLog(@"length=%zi", [@"我是字符串123" length]);
122     
123     // 取出對應的字符
124     unichar c = [@"abc" characterAtIndex:0];
125     NSLog(@"%c", c);
126     
127     // 返回C語言中的字符串
128     const char *s = [@"abc" UTF8String];
129     NSLog(@"%s", s);
130 }

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com