• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  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 }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Objective-C中的位运算符用法发布时间:2022-07-12
下一篇:
Objective-Cinstancetype关键字发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap