前言:做iOS开发有些时间了,日常开发上架都熟练于心了,然而连一些最基本的相关原理知识有时候都说不上来,想着有空的时候整理整理,写下来记录一下。可能了解的不够全面或者不够准确,如果有看到的朋友希望能不吝赐教。
1.alloc、init与new
alloc 分配内存
对象在分配内存空间时,会进行内存对齐,分配内存空间都是 16字节 的倍数。最小分配内存空间为16。
然而一个 NSObject 实例对象成员变量所占的大小,实际上是 8 字节,可通过class_getInstanceSize获得,而通过malloc_size可得出系统分配内存是16字节对齐。
(以上都是64位下)
看下图alloc在底层的走位
图片转自网络init 初始化
init方法啥也没做就返回了当前的对象,其他什么要做的救交给子类去自定义重写了。
详情可参考 iOS底层探索alloc和init
new等于 [[alloc]init] 分配内存,并且初始化。
通常不定制初始化时用new。
2、属性以及关键字
属性(property)有两大概念:ivar(实例变量)、存取方法(access method = getter + setter)。
属性底层实质
每增加一个属性,系统都会在 ivar_list 中添加一个成员变量的描述,在method_list中增加 setter 与 getter 方法的描述,在 prop_list中增加一个属性的描述。
成员变量 - 实例变量 - 属性
在{ }中所声明的变量都为成员变量。
实例变量本质上就是成员变量,只是实例是针对类而言,实例是指类的声明。
id 是OC特有的类,本质上讲id等同于(void *)。所以id data属于实例变量。
实例变量+基本数据类型变量=成员变量
person->name = @"kk" 给成员变量赋值
@synthesize与 @dynamic
完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。即使用@synthesize,Xcode4.5以后的版本默认的就是@syntheszie var = _var。找不到_var会自动生成一个叫做_var的私有成员变量。
使用@dynamic则需自己实现setter和getter方法。
使用场景:
1.父类定义了某个属性,子类想重新定义这个属性时,需要明确使用@synthesize或@dynmic,不然会有警告。但是具体是使用哪一个,就看你需不需要getter/setter方法了。
2.使用@dynamic动态绑定存取方法,可用消息转发实现。
3.NSManagedObject的属性由Core Data框架为此类属性运行时动态创建存取方法。
默认属性关键字 atomic,readwrite,strong
(1) atomic与nonatomic 原子性与非原子性
使用atomic编译器会在setter 方法中加锁(自旋锁)【不会给getter方法加锁】
避免多线程情况下的读写不同步,然而只保证了读和写的过程是可靠的,并不能保证数据一定是可靠的。线程安全是就getter,setter而言的。
atomic非常耗费系统资源,没有使用多线程间通讯普遍使用nonatomic避免耗费系统资源。
(2) readwrite与readonly 可读可写与可读
readwrite、readonly这两个属性的真正价值,不是提供成员变量的访问接口,而是控制成员变量的访问权限。
3、strong、weak、assign、copy
strong:强引用,其存亡直接决定了所指向对象的存亡,当强引用指向了某个对象,那便拥有了这个对象。引用计数+1。
weak:引用了某个对象但是并不拥有该对象。只可以修饰对象,否则编译会报错;weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃,是安全的。这两点也是与assign的主要区别。
weak原理:Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。
assign:对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)。如果用assign修饰对象,当对象被释放后,指针的地址还是存在的。
copy:多用于修饰有可变类型的不可变对象(NSString,NSArray,NSDictionary)
深拷贝 和 浅拷贝
1、对不可变的非集合对象,copy 是指针拷贝,mutablecopy 是内容拷贝
2、对于可变的非集合对象,copy,mutablecopy 都是内容拷贝
3、对不可变的数组、字典、集合等集合类对象,copy 是指针拷贝,mutablecopy 是内容拷贝
4、对于可变的数组、字典、集合等集合类对象,copy,mutablecopy 都是内容拷贝
想复制整个集合对象,就要用集合深复制的方法,有两种:
(1)使用 initWithArray:copyItems:方法,将第二个参数设置为 YES 即可
(2)将集合对象进行归档(archive)然后解归档(unarchive)。
部分内容转载自网络,如有侵权,敬请告知。
网友评论