内存管理篇: 6.不要使用静态和动态数组(非OC集合对象)
静态数组(类似于c数组,非OC的集合对象):
- 使用__strong、__weak和__autoreleasing修饰的静态数组(如:id objs[10]),其初始值也会自动赋值为nil,且当其释放时,子元素也会自动被释放;
动态数组(对象指针实现):
- 声明:
// 声明,指向id的指针:
id __strong *array = nil;
// 或 指向对象的指针
// NSObject * __strong *array = nil;
- 动态数组用对象指针表示;
- 由于对象指针默认为“__autoreleasing”修饰符,所以需要显示指定为“__strong”;
- 对象指针不会被ARC自动置为nil,需要显示指定。
- 初始化:
// 初始化:
array = (id __strong *)calloc(entries, sizeof(id));
// calloc方法会自动将内存空间写入0数据,比malloc配合memset更为安全且简洁
// 使用malloc和memset的错误方式
array = (id __strong *)malloc(sizeof(id) * entries);
for (NSUInteger i = 0; i < entries; ++i) {
array[i] = nil; // 错误:在ARC下相当于直接释放
}
- 使用:(与静态数组一致,同样不能放入nil)
array[0] = [[NSObject alloc] init];
- 释放:
// 1.依次释放子元素
for (NSUInteger i = 0; i < entries; ++i) {
array[i] = nil; // 在ARC下相当于直接释放对象
}
// 2.释放动态数组本身
free(array);
原因:由于动态数组是在运行期确定,ARC无法在编译器对其进行内存管理,直接释放数组本身会让子元素发生内存泄漏。
补充:
使用memcpy拷贝数组中的元素和realloc重新分配内存,都可能导致对象内存泄漏或过度释放,所以ARC下也被禁止使用。
结论:
直接使用Foundation的集合对象就好了,不要用这种东西。