原文:http://rypress.com/tutorials/objective-c/data-types/nsstring

NSString

在本教程的内容可能我们已经看到过很多次了,NSString类是OC应用中文本的基础工具类。除了提供面向对象的字符串外,它也提供了很多强大的方法去操作字符串内容。同时也支持本地的编码支持。

就像NSNumber和NSDecimalNumber,NSString 是不可变类型,所以你不能对他进行修改。在本章最后我们将讨论NSMutableString,这个类是可变字符串。

创建字符串

最最常用的创建方法就是使用@"Some String"语法操作,但是stringWithFormat:方法在提供格式化创建字符串方面很好用:

NSString *make = @"Porsche";
NSString *model = ";
;
NSString *message = [NSString stringWithFormat:@"That's a %@ %@ from %d!",
                     make, model, year];
NSLog(@"%@", message);
注意到我们在NSLog()方法中使用@”%@“格式化信息进行输出而不是直接NSLog(message)。这样做才是最佳实践,因为有可能在message中存在着%字符导致问题。想想如果
message = @"The tank is 50% full"
NSString提供了很多内置的编码,也就是说你能在字符串中直接使用UTF-8的字符。例如,你可以使用如下字符串如同其他字符串根本没有任何区别。
NSString *make = @"Côte d'Ivoire";

枚举字符串

NSString两个最主要的基础方法是length和characterAtIndex:方法,分别放回当前字符串的字符数和字符串中指定位置的字符,虽然可能很少使用到他们,但是还是需要了解一下比较好:

NSString *make = @"Porsche";
; i<[make length]; i++) {
    unichar letter = [make characterAtIndex:i];
    NSLog(@"%d: %hu", i, letter);
}

字符串比较

字符串的比较很NSNumber的比较很相像。除了你需要比较指针是否相等外,你还需要使用isEqualToString:方法去做更加详细的内容比较。下面的例子展示了这个原理,在代码中使用了 hasPrefix: 和 hasSuffix:方法

NSString *car = @"Porsche Boxster";
if ([car isEqualToString:@"Porsche Boxster"]) {
    NSLog(@"That car is a Porsche Boxster");
}
if ([car hasPrefix:@"Porsche"]) {
    NSLog(@"That car is a Porsche of some sort");
}
if ([car hasSuffix:@"Carrera"]) {
    // This won't execute
    NSLog(@"That car is a Carrera");
}

就像NSNumber,NSString有一个compare:方法,他在让字符串进行字典排序的时候非常有用。

NSString *otherCar = @"Ferrari";
NSComparisonResult result = [car compare:otherCar];
if (result == NSOrderedAscending) {
    NSLog(@"The letter 'P' comes before 'F'");
} else if (result == NSOrderedSame) {
    NSLog(@"We're comparing the same string");
} else if (result == NSOrderedDescending) {
    NSLog(@"The letter 'P' comes after 'F'");
}

上述的方法是大小写敏感的,如果忽略大小写  则需要使用caseInsensitiveCompare:方法,

字符串组合

下面代码展示了两个方法去组合字符串。但是,记住由于NSString本身是不可变的,所以组合后将生成一个新的字符串,而原有字符串不会被改变。

NSString *make = @"Ferrari";
NSString *model = @"458 Spider";
NSString *car = [make stringByAppendingString:model];
NSLog(@"%@", car);        // Ferrari458 Spider
car = [make stringByAppendingFormat:@" %@", model];
NSLog(@"%@", car);        // Ferrari 458 Spider (note the space)

搜索字符串

所有的NSString的搜索方法都将返回NSrange结构体,结构体中定义了location和length变量,location是搜索到的开始位置,length是搜索到的总字符数。如果没有搜索到,location值将为NSNotFound。例如下面的代码片段:

NSString *car = @"Maserati GranCabrio";
NSRange searchResult = [car rangeOfString:@"Cabrio"];
if (searchResult.location == NSNotFound) {
    NSLog(@"Search string was not found");
} else {
    NSLog(@"'Cabrio' starts at index %lu and is %lu characters long",
          searchResult.location,
          searchResult.length);
}

分隔字符串

你可以指定位置的方式来分隔一个字符串,但是记住,由于NSString是不可变,所以分隔后返回的值是一个全新的字符串,远字符串不会被修改。

NSString *car = @"Maserati GranTurismo";
NSLog(]);               // Maserati
NSLog(]);             // GranTurismo
NSRange range = NSMakeRange(, );
NSLog(@"%@", [car substringWithRange:range]);         // Gran

NSMakeRange()是一个全局方法,用于创建NSRange结构体变量。第一个参数是location值,而第二个是length值。substringWithRange:通过NSRange来切分字符串。

我们也可以将字符串通过componentsSeparatedByString:方法将其切割进数组中,如:

NSString *models = @"Porsche,Ferrari,Maserati";
NSArray *modelsAsArray = [models componentsSeparatedByString:@","];
NSLog(]);        // Ferrari

替换字符串

替换字符串的部分内容和切割字符串很像,下面的代码展示了如何做:

NSString *elise = @"Lotus Elise";
NSRange range = NSMakeRange(, );
NSString *exige = [elise stringByReplacingCharactersInRange:range
                                                 withString:@"Exige"];
NSLog(@"%@", exige);          // Lotus Exige
NSString *evora = [exige stringByReplacingOccurrencesOfString:@"Exige"
                                                   withString:@"Evora"];
NSLog(@"%@", evora);          // Lotus Evora

大小写转化

NSString类也提供了一些方便的方法去进行字符串的大小写转化处理。

NSString *car = @"lotUs beSpoKE";
NSLog(@"%@", [car lowercaseString]);      // lotus bespoke
NSLog(@"%@", [car uppercaseString]);      // LOTUS BESPOKE
NSLog(@"%@", [car capitalizedString]);    // Lotus Bespoke

数字转换

NSString定义了几个字符串转换为基本类型的方法。但是如果你需要保证代码的健壮最好还是使用 NSScanner 或者NSNumberFormatter

NSString *year = ";
BOOL asBool = [year boolValue];
int asInt = [year intValue];
NSInteger asInteger = [year integerValue];
long long asLongLong = [year longLongValue];
float asFloat = [year floatValue];
double asDouble = [year doubleValue];

NSMutableString

NSMutableString是NSString的可变版本。不像不可变字符串,可变字符串可以修改原有字符串而不需要重新建立一个新的字符串。

NSMutableString继承自NSString,所以基本上在NSString中可以使用的方法你都可以在NSMutableString中使用。虽然 stringByAppendingString:方法依然返回NSString对象而不是NSMutableString对象。

接下来的小节中展示一些NSMutableString中特有的方法。从中你会发现两者在操作套路上的差别。不像NSString会从新创建新的对象,NSMutableString则直接在原有对象上进行操作。

创建可变字符串

可变字符串可以可以使用stringWithString:方法爱接受一个直接定义的字符串或者一个已经存在的NSString字符串变量来创建。

NSMutableString *car = [NSMutableString stringWithString:@"Porsche 911"];

对象创建完毕后你可以通过setString:方法爱重新给他赋值。

[car setString:@"Porsche Boxster"];

扩展可变字符串

NSMutableString和NSString的最主要区别就是前者直接在原有的内存中操作而后者会新建对象。

NSMutableString *car = [NSMutableString stringWithCapacity:];
NSString *model = @"458 Spider";

[car setString:@"Ferrari"];
[car appendString:model];
NSLog(@"%@", car);                    // Ferrari458 Spider

[car setString:@"Ferrari"];
[car appendFormat:@" %@", model];
NSLog(@"%@", car);                    // Ferrari 458 Spider

[car setString:@"Ferrari Spider"];
[car insertString:];
NSLog(@"%@", car);                    // Ferrari 458 Spider

替换/删除子字符串

通过replaceCharactersInRange:withString:和deleteCharactersInRange:方法可以达到此目的:

NSMutableString *car = [NSMutableString stringWithCapacity:];
[car setString:@"Lotus Elise"];
[car replaceCharactersInRange:NSMakeRange(, )
                   withString:@"Exige"];
NSLog(@"%@", car);                               // Lotus Exige
[car deleteCharactersInRange:NSMakeRange(, )];
NSLog(@"%@", car);                               // Lotus

什么时候适合使用可变字符串呢?

既然NSString和NSMutableString提供的功能差不多,所以很难说用哪个好。一般来说,NSString的静态属性在大多数时候更加高效。但是如果要修改字符串值的话有需要去新创建对象。

下面展示两个例子来展示可变字符串的优势。第一个例子中展示不可变字符串:

// DO NOT DO THIS. EVER.
NSString *indices = @"";
; i<; i++) {
    indices = [indices stringByAppendingFormat:@"%d", i];
}
记住stringByAppendingFormat:方法始终会创建一个NSString对象,上述过程大概需呀1.76MB。不必多说,这样的效率真的很低。

现在可变字符串的表现:

NSMutableString *indices = [NSMutableString stringWithCapacity:];
; i<; i++) {
    [indices appendFormat:@"%d", i];
}

既然可变字符串没有新建对象,没有发生对象间的拷贝,这个过程大概只要19KB内存。

所以,一个好的规则就是,在一个逻辑中如果需要修改对象则使用可变字符串,除此之外全部应该使用不可变字符串,这点也适用于setsarrays, and dictionaries.

12-4 NSString的更多相关文章

  1. iOS开发Extra系列:NSString***

    在iOS系统,NSString可能是最常用的对象,很多用法跟其他语言不一样. 字符串对象NSString 使用格式创建字符串 1 2 3 4 5 + (id)stringWithFormat:(NSS ...

  2. Objective-C学习篇06—NSString与NSMutableString

    NSString OC提供了定义字符串对象的方法,也就是将想要表达的字符串用一对双引号引起来,并在开头加上@.@是OC中的指令符,它告诉编译器@以后的内容为OC中的语法.比如@”Harbingwang ...

  3. OC基础12:数字、字符串和集合1

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.有时要将一些数字数据类型的值当做对象来 ...

  4. IOS 杂笔-9 (MD5 加密)

    首先是一段对MD5的简介 *出自一位大牛之手* Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护 ...

  5. 黑马程序员_ Objective-c 之Foundation之NSNumber ,NSValue, NSDate

    Objective-c 之Foundation之NSNumber ,NSValue, NSDate 1.NSNumber具体用法如下: 在Objective-c中有int的数据类型,那为什么还要使用数 ...

  6. iOS开发——高级技术OC篇&运行时(Runtime)机制

    运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档 ...

  7. 使用TextKit

    使用TextKit TextKit是在iOS7中新出的,实现了对CoreText的封装,使用起来更加方便. 虽然是新出的,但也不代表立马就能上手-_-!!,TextKit可以实现图文混排效果,很好用. ...

  8. 将报表移动端集成到自有移动端app方法【IOS、Android】

    应用场景 用户有自己的app,希望把报表的移动端[本文中以FineReport移动端为例]功能集成到他们的app里面去,而不需要安装两个app.Android端和IOS端的集成接口是不一样的,下面我们 ...

  9. 获取唯一UUID/UDID方案

    概述 如何保证获取到的UUID能够唯一标识每一台设备呢?我们知道通过UIDevice可以获取到UUIDString,但是如果App被删除了然后重新安装,就会得到不同的UUIDString,这并不是我们 ...

  10. IOS文字属性备注

    // Predefined character attributes for text. If the key is not in the dictionary, then use the defau ...

随机推荐

  1. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

  2. springmvc不通过controller进行页面跳转

    1.controller 继承WebMvcConfigureAdapter 然后使用ViewControllerRegistry  来进行跳转

  3. Selenium判断获取的元素是否可见(display:none)

    在爬虫中需要自动登陆并判断是否登陆成功,如果登陆错误的话还需要知道错误提示信息,此时需要判断提示信息是否可见 if self.element_exist_xpath('//*[@id="bu ...

  4. arm-linux-gcc等交叉编译工具的安装

    1.软件安装 步骤1:打开虚拟机,在/usr/local/下创建/usr/local/arm文件夹(一般用户自定义程序放到这里) 步骤2:先将安装包从Windows中弄到linux中去.可以用共享文件 ...

  5. Jupyter生成中文PDF的Notebook

    修改模板文件,将article.tplx文件中的\documentclass[11pt]{article}改为\documentclass[11pt]{ctexart} Linux下的文件路径一般在: ...

  6. Struts整合ExtJS

    1准备工作: 除了平时引入的struts2的jar包以外,还需要引入struts2-json-plugin-2.1.8.1.jar:json-lib-2.1.jar这两个包. 2.建立我们的model ...

  7. NOI2001 方程的解数

    1735 方程的解数 http://codevs.cn/problem/1735/ 2001年NOI全国竞赛  时间限制: 5 s  空间限制: 64000 KB     题目描述 Descripti ...

  8. 2015/8/28 Python基础(2):对象

    Python用对象模型来存储数据.构造任何类型的值都是一个对象.Python对象都有是三个特性:身份,类型和值 身份是每个对象的唯一身份标识.任何对象都可以用内建函数id()来得到身份.如: > ...

  9. [洛谷P2577] [ZJOI2005]午餐

    洛谷题目链接:[ZJOI2005]午餐 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的 ...

  10. 【poj2104-求区间第k大数(不修改)】主席树/可持续化线段树

    第一道主席树~然而是道比较水的...因为它不用修改... 转载一个让我看懂的主席树的讲解吧:http://blog.csdn.net/regina8023/article/details/419106 ...