內(nèi)存管理篇: 6.不要使用靜態(tài)和動態(tài)數(shù)組(非OC集合對象)
靜態(tài)數(shù)組(類似于c數(shù)組,非OC的集合對象):
- 使用__strong、__weak和__autoreleasing修飾的靜態(tài)數(shù)組(如:id objs[10]),其初始值也會自動賦值為nil,且當(dāng)其釋放時,子元素也會自動被釋放;
動態(tài)數(shù)組(對象指針實現(xiàn)):
- 聲明:
// 聲明,指向id的指針:
id __strong *array = nil;
// 或 指向?qū)ο蟮闹羔?// NSObject * __strong *array = nil;
- 動態(tài)數(shù)組用對象指針表示;
- 由于對象指針默認(rèn)為“__autoreleasing”修飾符,所以需要顯示指定為“__strong”;
- 對象指針不會被ARC自動置為nil,需要顯示指定。
- 初始化:
// 初始化:
array = (id __strong *)calloc(entries, sizeof(id));
// calloc方法會自動將內(nèi)存空間寫入0數(shù)據(jù),比malloc配合memset更為安全且簡潔
// 使用malloc和memset的錯誤方式
array = (id __strong *)malloc(sizeof(id) * entries);
for (NSUInteger i = 0; i < entries; ++i) {
array[i] = nil; // 錯誤:在ARC下相當(dāng)于直接釋放
}
- 使用:(與靜態(tài)數(shù)組一致,同樣不能放入nil)
array[0] = [[NSObject alloc] init];
- 釋放:
// 1.依次釋放子元素
for (NSUInteger i = 0; i < entries; ++i) {
array[i] = nil; // 在ARC下相當(dāng)于直接釋放對象
}
// 2.釋放動態(tài)數(shù)組本身
free(array);
原因:由于動態(tài)數(shù)組是在運行期確定,ARC無法在編譯器對其進行內(nèi)存管理,直接釋放數(shù)組本身會讓子元素發(fā)生內(nèi)存泄漏。
補充:
使用memcpy拷貝數(shù)組中的元素和realloc重新分配內(nèi)存,都可能導(dǎo)致對象內(nèi)存泄漏或過度釋放,所以ARC下也被禁止使用。
結(jié)論:
直接使用Foundation的集合對象就好了,不要用這種東西。