这是我参与「第四届青训营 」笔记创作活动的的第4天
浅拷贝与深拷贝
浅拷贝:仅拷贝指针,复制一个指针,指向同一块内存区域,实际内存并没有发生拷贝
深拷贝:内容拷贝,拷贝数据到新的一块内存区域,指针指向拷贝的数据区
可变对象与不可变对象的拷贝行为——以NSString为例
1.The address of [NSString copy] is the same as NSString
While the address of [NSString mutableCopy] is different from NSString
对于NSString复制是浅拷贝,可变复制是深拷贝
2.The address of [NSMutableString copy]&[NSMutableString mutableCopy] are different from NSString
对于NSMutableString(可变对象)两种拷贝方式都是深拷贝,而[NSMutableString copy]本质是在内存里创建了一个NSString对象, [NSMutableString mutableCopy]本质是在内存里创建了一个NSMutableString的对象
3.Summary:代码中,深拷贝在转换可变对象与不可变对象中常常用到
@property权限修饰下的拷贝行为
对于@propertry copy修饰下的NSString 无论是哪一种拷贝 地址都相同
代码中一般用copy修饰不可变对象,防止传入NSMutableString不管传入对象是可变的还是不可变的,都可以保证自己持有的是不可变的副本,初始化后不会被外部修改所影响。
Strong只是强指针的指向
闭包与Objective-C block
计算机语言中、 “闭包(Closure) 是由函数和与其相关的引用环境组合而成的实体。”
Block是OC语言对闭包的实现,闭包除具备“函数和函数指针”的所有功能外, 还包括声明它的上下文(如作用域内的自由变量等)。
block基础
block是闭包在Objective-C中的实现
Block可以接受参数,也可以有返回值
Block可以分配在栈&堆上,也可以是全局的。分配到栈上的块可以拷贝到堆中,与标准的Objective-C对象一样,具备引用计数
Block的标准格式:returnType (^blockName)(Paras);
^returnType(parameters){
//do the service logic
};
Eg:int (^sumBlock) (int a, int b) =^int(int a, int b) {
return a+B;//简便写法
}
Int sum = sumBlock(1,1)//调用
进一步简便
Void (^printBlock)(void) =^{
NSLog{@“Hello World!”};
};
Block的typedef
typedef returnType (^blockName)(parameters);
Eg:
Block的内存管理
在Objective-C语言中,一共有3种类型的block:
1、_NSConcreteGlobalBlock 保存在text段的全局的静态block,不会访问任何外部变量。
2、_NSConcreteStackBlock 保存在栈中的block,当函数返回时会被销毁。
3、_NSConcreteMallocBlock 保存在堆中的block,当引用计数为0时会被销毁。(ARC)
!注意block循环引用问题
在block内直接调用类的实例变量会使self(类的实例)引用计数加1, 这样可能会引起循环引用问题(可以用__weak或local-var处理);
-
变量捕获
- Block的值引用,对于普通c变量在block的引用,是获取在初始化时的c变量值,在block初始化定义之后出现的值的改变不影响block方法调用的结果。
- Block的名称引用,对于普通c变量若由__block关键字修饰,则是名称引用,即在方法调用之前所有的变量值的修改都会影响;捕获对象的属性@property(nonatomic,copy)NSString *name
- Block的循环引用例子与解决见图