zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/yif1991/p/5067005.html
Copyright © 2011-2022 走看看