字符串(NSString)
-初始化字符串的几种方法
1.字面常量初始化
NSString *str1 = @"Hello World";
2.工厂化
NSString *str2 = [NSString stringWithCString:"hello world" encoding:NSUTF8StringEncoding];
3.初始化器
NSString *str2 = [[NSString alloc]initWithCString:"hello world" encoding:NSUTF8StringEncoding];
:"hello world" encoding:NSUTF8StringEncoding];
-字符串是一个引用类型 (NSString *str1) 同时拷贝时具有引用语义
-字符串的几个特性
1.字符串具有恒定性 所有的修改无法改变字符串本身 如果有改变则回返回一个新字符串 例:
NSString *str1 = @"hello world";
打印出的指针地址为:
Paste_Image.png
当str1修改以后
str1= [str1 stringByAppendingString:@"!!"];
打印的地址为:
Paste_Image.png
由此不难看出 当字符串初始化以后 无法对字符串本身进行修改 如果修改 返回的都是新的字符串 并不改变原有字符串 等于修改了指针所指向的对象
2.字符串拥有共享机制(只针对于字面常量方法初始化字符串) 例:
NSString *str1 = @"Hello World";
NSString *str4 = @"Hello World";
Paste_Image.png
Paste_Image.png
可以看出 str1和str4的指针地址完全相同 也就是说 str1 和str4栈上的指针都指向堆上的对象 对象是Hello World 同时由于该机制 引用计数对其的管理 也有特殊的管理规则
可变字符串(NSMutableString)
-可变字符串具有可变性 也就是说字符串初始化以后 本身是可以修改的 和NSString相反
-可变字符串不具有共享性
-NSMutableString是NSString的子类
-NSMutableString初始化时 需要注意的点:
1.由于NSMutableString的增长方式并不是在原有内存上增长 其分配的内存的方式是重新分配一个更大或者更小的缓存容量 所以 我们需要在一开始就预估好Capacicy
2.如果预估的Capacity实际需求的Capacity则会发生以下情况
-分配新的堆内存 2*Capacity
-将原有堆内存上的内容拷贝到新的内存上
-释放原有的内存
终上所述 我们在初始化NSMutableString时尽量预估好Capacity 避免日后Capacity增长
集合类型
1.数组(Array和NSMutableArray)
-数组被定义为Class 是引用类型 拷贝时具有引用语义
-数组是一个有序的集合 数组下标从0开始 在使用时 如果发生越界 则会导致程序崩
-数组的元素必须是对象 也就是NSObject的子类
-数组具有常量性 元素的长度和元素指针都不能修改 但是可以修改指针指向的对象内部可以修改
2.遍历数组的三种方式
for in循环(最快)
for ( BLNPoint* point in array5)
{
point.x++;
point.y++;
}```
迭代器NSEnumerator遍历(稍慢)
NSEnumerator *enumerator = [array5 objectEnumerator];
BLNPoint* item;
while (item = [enumerator nextObject])
{
item.x++;
item.y++;
}
for循环(最慢)
for (int i=0; i<array5.count; i++) {
NSLog(@"array5[%d],%@",i,array5[i]);
}
#可变数组(NSMutableArray)
-NSMutableArray是Array的子类
-NSMutableArray支持更改元素的指针和数组长度
-NSMutableArray初始化时需注意的点和NSMutableString一样(Capacity)
#集合(NSSet)
-NSSet是一个无序的集合 其存储的对象不能重复
-NSSet被定义为Class 是引用类型 拷贝时具有引用语义
-NSSet是一个常量集合 具有常量性(同NSArray)
-NSSet支持for in遍历和迭代器遍历 for in最快
#可变集合(NSMutableSet)
-初始化NSMutableSet时候也需要注意Capacity
#字典(Dictionary)
-Dictionary是一个无序集合 其内部存储Key - Value 需注意 Key唯一 但是Value可以是多个
-Dictionary也是Class 引用类型 拷贝时具有引用语义
-Dictionary分为常量字典(NSDictionary)和可变字典(NSMutableDictionary)
-常量字典拥有常量性(同NSArray一样)
-初始化NSMutableDictionary也需要注意Capacity
-Dictionary支持for in遍历和迭代器遍历 for in最快
#自动引用计数 ARC
-ARC是Objective-C中默认的内存管理机制 针对堆上的对象 编译器自动生成操作引用计数的指令(relaease和retain)来管理对象的创建和释放
-受到ARC管理的对象:
1.OC对象指针
2.Block指针
3.使用__attribute__((NSObject))定义的typedef
-不受ARC管理的对象:
1.值类型
2.非内存资源
3.使用其他方式分配的堆对象
-引用计数管理:
1.新创建一个引用类型对象 引用计数为1 (copy,alloc,new)
2.引用计数+1(retain)常见操作有
-将对象引用赋值给其他对象或常量
-将对象引用赋值给其他属性或实例变量
-将对象传递给函数参数或者返回值
-将对象加入集合中
3.引用计数-1(relaease)常见操作有
-将对象从集合中删除
-参数或局部变量离开函数
-实例属性所在的对象被释放
-将属性赋值为nil或其他值
-将局部变量或全局变量赋值为nil或其他值
4.当引用计数为0时 对象自动释放 谁引用谁负责释放
#类型合同:协议(Protocol)
-协议:类型的合同约定 只提供对外接口不提供实现
-协议包含的成员:
1.属性
2.实例方法
3.类方法
4.析构器(不常用)
5.初始化器(不常用)
-需注意 协议中无法包含实例变量
-使用协议需注意的点:
1.需要@required协议中所有约定的成员(不写required也默认为required)
2.协议本质是一种类型 可以作为类型 但不能创建实例
3.一个协议可以继承一个或者多个协议
4.实现子协议的类型 也必须实现父类协议中约定的所有成员
5.可以通过protocl<A,B,...>来组合多个协议
6.协议的类型成员也可以是可选(optional) 不必实现
-常用协议
NSObjective NSCopying NSMutableCopying NSFastEnumeration NSCoding
#类别与拓展
-类别(Categroy):可以在没有源代码的情况下 为某个类添加功能 如作业中给NSMutableArray类添加一个"捕捞方法"
-命名规范:类名+拓展方法 如:NSMutableArray+Catch.h .m文件同理
-类别可以添加的方法有:
1.类方法
2.实例方法
3.重写基类方法
-以下情况类别中不能添加:
1.属性
2.实例变量
3.已存在的同名方法
-拓展(Extension):可以在有源代码的情况下 为类添加功能
-拓展定义在.m文件中 同时在@implementation前声明 实现依然在其内部实现
-拓展可以添加的成员:
1.实例变量
2.属性
3.类方法
4.实例方法
5.修改属性的读写属性(只能从小到大修改)
网友评论