字符串处理相关

字符串处理

认识字符串NSString

  • NSString 是一个Unicode编码、16位字符的字符序列
  • NSString 被定义为类,引用类型,拷贝时具有引用语义
  • 初始化方法:字面量初始化、初始化器、工厂方法。
  • NSString拥有恒定性,所有的操作无法更改字符串本身,如有更改,都是返回新值的形式
  • NSString 拥有共享机制,引用计数管理对其有特殊的管理规则。

%p表示地址

NSMutalbeString

  • NSMutableString具有可变性,NSString具有恒定性。
  • NSMutableString是NSString的子类。
  • NSMutableString不具有共享机制,NSString具有共享机制。
  • NSMutableString并不是在原有内存上直接增长,而是重新分配一个更大或更小的缓存容量存放字符。

NSString 常用操作

  • NSString:
    • 访问字符串:获取字符串字符、字符串长度、字面量、大小写转换。
    • 查询字符串:定位子串、是否包含子串、查询字符集
    • 其他操作:比较字符串、替换字符串、分解字符串。
  • NSMutableString
    • 添加字符串
    • 删除字符串
    • 修改字符串

集合类型

认识数组

  • 数组是一个有序的元素序列,支持随机存取。索引从0开始,索引访问越界会抛出运行时异常。注意与C语言数组不同。
  • NSArray的元素定义为class,引用类型,拷贝时具有引用语义
  • NSArray的元素必须是对象,即NSObject的子类
    • 如为基本数值类型,须用NSNumber封装为对象类型后,才能放入数组中。
    • 如为C语言结构类型,须用NSValue封装为对象类型后,才能放入数组中。
    • 数组元素可以是不同对象类型,可能会有类型不安全。
  • NSArray具有常量性:长度和元素指针都不能更改。但指针指向的对象内部可以更改。

常用操作

  • 数组遍历
    • 最快 -- Fast Enumeration,直接访问内存,优化索引检查,快5-10倍
    • 较慢 -- NSEnumerator遍历:索引检查+动态消息调用
    • 最慢 -- For 循环访问:索引检查+动态消息调用
  • 数组查找
    • indexOfObject 查找是否存在“值相等”的对象(类型需要实现isEqual)
    • indexOfObjectIdenticalTo查找是否存在“指针相等”的对象
  • 数组排序
    *不改变原数组(常量性),返回新数组。

使用NSMutableArray

  • NSMutableArray支持更改数组长度和元素指针。为NSArray子类。
  • NSMutableArray初始化后,会分配一个缓存容量capacity,一般大于实际元素数量,当元素长度增加时,如实际需求大于capacity,其capacity会以近似二倍的方式指数增长。伴随代价:
    • 分配新的堆内存 2*capacity
    • 将原来堆内存上的元素拷贝到新内存
    • 释放原来的堆内存
  • 最佳实践:估计好capacity,预先分配一定容量,避免以后增长
  • 尽量避免使用insertObject:atIndex;和removeObjectAtIndex;等操作,因为会改变数组元素序列,涉及大量内存拷贝操作,代价高。(假如我有这种需要呢?)

认识Set

  • NSSet是一个无序的集合,其存储的对象不能重复

  • NSSet被定义为class,引用类型,拷贝时具有引用语义

  • 常量集合NSSet,可变集合:NSMutableSet:

    • 常量性:长度和元素指针都不能改变。但指针指向的对象内部可以更改。
    • 创建NSMutableSet时用initWithCapacity提前设置capacity
  • 支持Fast Enumeration和NSEnumerator遍历,前者较快。

认识Dictionary

  • NSDictionary是一个存储key-value的无序集合,key唯一,value可重复
  • NSDictionary被定义为class,引用类型,拷贝时具有引用语义。
  • 常量集合NSDictionary,可编辑和:NSMutableDictionary:
    • 常量性:长度和元素指针都不能更改。但指针指向的对象内部可以更改。
    • 创建NSMutableDictionary时用initWithCapacity提前设置capacity
  • 支持Fast Enumeration和NSEnumerator遍历,前者较快。

自动技术引用ARC

  • 自动引用计数(Automatic Reference Counting)是Objective-C默认的内存管理机制,其针对堆上的对象,由编译器自动生成操作引用计数的指令(retain或release),来管理对象的创建与释放。
  • 那些对象受ARC管理:
    • OC对象指针
    • Block指针
    • 使用attribute((NSObject))定义的typedef
  • 那些对象不受ARC管理:
    • 值类型(简单值类型,c语言struct)
    • 使用其他方式分配的堆对象(如使用malloc分配)
    • 非内存资源

引用计数管理

  • 新创建(使用alloc, new, copy等)一个引用类型对象,引用计数为1
  • 对象引用计数增1--retain操作
    • 将对象引用赋值给其他变量或常量
    • 将对象引用赋值给其他属性或实例变量
    • 将对象传递给函数参数,或者返回值
    • 将对象加入集合中
  • 对象引用计数减1--release操作
    • 将局部变量或全局变量赋值为nil或其他值
    • 将属性赋值为nil或其他值
    • 实例属性所在的对象被释放
    • 参数或局部变量离开函数
    • 将对象从集合中删除
  • 引用计数变为0时,内存自动被释放。

自动释放池(Autorelease Pool)

  • release会导致对象立即释放。如果频繁对对象进行release,可能会造成琐碎的内存管理负担。autorelease可以将release的调用延迟到自动释放池被释放时。
  • 推荐使用自动释放池(Autorelease Pool)Block,当其结束时,所有接受autorelease消息的对象就会被立即释放(即发送release消息)
  • AppKit和UIKit框架在处理每一次事件循环迭代时,都会将其放入一个Autorelease Pool中。大多数情况,无需程序员干预。

什么时候需要手工管理Autorelease Pool

  • 编写的程序不基于UI框架,如命令行程序。
  • 在循环中创建大量临时对象,需要更早地释放,避免临时对象聚集导致内存峰值过大。
  • 在主线程之外创建新的线程,在线程开始执行出,需要创建自己的Autorelease Pool
  • 可以签到使用Autorelease Pool

类型合同:协议

认识协议Protocol

  • 协议:类型的合同约定,只描述外部接口,不提供具体实现
  • 协议可以包含以下成员:
    • 属性
    • 实例方法
    • 类方法
    • 初始化器-不常用
    • 析构器 - 不常用
  • 协议中无法包含实例变量成员
  • 协议中定义的属性本质上是访问器方法,编译器不会合成实例变量。

使用协议

  • 一个类遵守协议,需要实现协议约定的所有@required成员
    • 协议中的属性项目须在实现类的.h文件中声明(编译器合成实例变量需要)。
  • 注意编译警告信息:
    • 遵守协议后却没有实现必选协议方法时,会出现警告提示。
    • 协议类型变量被赋值非协议类型对象时,会出现警告提示。
  • 协议本质上是一种类型,可以作为声明类型,但不能创建实例。
  • 检查协议类型
    • 使用conformsToProtocol:检查对象是否实现了协议

更多协议形式

  • 协议继承
    • 一个协议可以继承一个或多个协议
    • 实现子协议的类型,也必须实现父协议中约定的成员
  • 协议组合
    • 可以使用protocol<A,B,...>来组合多个协议
    • 实现组合协议的类型,必须实现组合协议中的每一个协议
  • 可选协议
    • 协议的某些成员可以定义为optional,不必实现。

了解常用协议

  • NSObject:包含对象的常用操作,相等、字符串表示、哈希
  • NSCopying:支持赋值的类型必须遵守该协议
  • NSMutableCopying:在NSCopying协议的基础上,支持赋值数据的可变性。
  • NSFastEnumeration:实现快速枚举for-in的类型采用。
  • NSCoding协议:支持将对线图进行编码/解码以支持对象序列化。

类别 Category

  • 类别支持在没有源代码的情况下,基于某些特定的场合,为一个类增加功能。

  • 可以添加

    • 类方法
    • 实例方法
    • 重写基类方法
  • 不能添加

    • 属性
    • 实例变量 (相当于更改类的内存模型)
    • 已存在的同名方法
  • 命名规范

    • 文件名:类名+扩展方法,如:NSString+Drawing.h/.m

扩展 Extension

  • 扩展支持在编译时、有类的源代码的前提下,向类添加功能。可以将扩展看做匿名的类别。
  • 接口定义在.m文件中@implementation钱声明,实现代码仍然在@implementation内实现。
  • 扩展支持添加一下成员:
    • 添加属性
    • 添加实例成员
    • 添加类方法
    • 添加实例方法
    • 改写属性的读写属性

使用扩展

  • 扩展实现的成员都只能在.m实现文件内部访问,在类外不可以直接访问。
  • 扩展的主要用途在于信息隐藏,隐藏一些外部无需访问、而内部实现又需要使用的属性、方法:
    • 类的主接口主要用于“对类外公开”的接口
    • 类的扩展接口用于“对类内可见”的接口。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容