简体   繁体   English

我必须保留NSMutableArray,尽管它是一个属性

[英]I have to retain a NSMutableArray although it's a property

I'm new, but I read a lot about memory management, and really tried to find the answer myself. 我是新手,但是我读了很多有关内存管理的文章,并真的试图自己找到答案。 It sounds so basic and yet I apparently don't get it. 听起来很基本,但我显然不明白。 I have a NSMutableArray as property in .h: 我在.h中有一个NSMutableArray作为属性:

@property (nonatomic, retain) NSMutableArray *documentListArray;

I synthesize it and release it in (void) dealloc. 我将其合成并在(void)dealloc中释放它。 To populate the array, I have a method - (void)updateRecordList and in there: 要填充数组,我有一个方法-(void)updateRecordList,其中:

self.documentListArray=[DocumentDatabase getDocumentListSortedByDate];

EDIT:next line: 编辑:下一行:

[[self recordListTableView] reloadData];

where DocumentDatabase is a different class with the class methods getDocumentListSortedByDate and getDocumentList. 其中DocumentDatabase是具有类方法getDocumentListSortedByDate和getDocumentList的其他类。 Here is what is happening in getDocumentListSortedByDate: 这是getDocumentListSortedByDate中发生的事情:

NSMutableArray *returnArray = [DocumentDatabase getDocumentList];
//sorting...
NSLog("array count:%i",[returnArray count]); //returns correct numbers first and second time
return returnArray;

and in getDocumentList 并在getDocumentList中

NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:files.count];
//add file data to array...
return returnArray;

This works the first time I call updateRecordList, but after adding a file and calling updateRecordList a second time, it crashes with (using NSZombies): * -[NSCFNumber dealloc]: message sent to deallocated instance 0x7504c90. 这在我第一次调用updateRecordList时有效,但是在添加文件并再次调用updateRecordList之后,它崩溃(使用NSZombies): * -[NSCFNumber dealloc]:发送到已释放实例0x7504c90的消息。 With a lot of logging I narrowed the problem down to the line above in updateRecordList and it works if I change it to: 通过大量的日志记录,我将问题缩小到了updateRecordList中的上一行,并且如果将其更改为以下内容,则可以正常工作:

self.documentListArray=[[DocumentDatabase getDocumentListSortedByDate] retain];

My conclusion is that the array down in getDocumentList has been autoreleased before it arrives. 我的结论是,getDocumentList中的数组在到达之前已自动释放。 So my questions are: 所以我的问题是:
1. Why do I have to retain it there? 1.为什么我必须保留它? Shouldn't that happen by itself by declaring the property (retain)? 这不是通过声明属性(保留)本身发生的吗? Or, in other words, why is the array autoreleased too early (assuming this is what is happening)? 或者,换句话说,为什么数组过早自动发布(假设正在发生这种情况)?
2. When I assign a new array to self.documentListArray, is the old array automatically released? 2.当我为self.documentListArray分配一个新数组时,旧数组会自动释放吗? If I try to release it myself before getting a new documentList, it crashes too. 如果在获取新的documentList之前尝试自己释放它,它也会崩溃。

Thanks in advance for any reply. 预先感谢您的任何答复。

EDIT: Maybe I'm an idiot: I failed to mention that documentListArray is the data source for an UITableView (see the added line on top). 编辑:也许我是个白痴:我未能提及documentListArray是UITableView的数据源(请参见顶部的添加行)。 I suspect that I am doing something wrong with populating the table view, and the array gets retained...? 我怀疑我在填充表视图时做错了什么,并且数组被保留了...? It does however crash on assigning the property, not on reloadData. 但是,它确实会在分配属性时崩溃,而不是在reloadData上崩溃。 I go back to study if I use the UITableViewDataSource protocol properly. 我回去研究是否可以正确使用UITableViewDataSource协议。 Thanks to everybody, your answers brought me hopefully on the right track. 谢谢大家,您的回答使我有望走上正确的道路。 Will update when solved. 解决后将更新。

EDIT2: It works now without retaining, and I think I understand why: I debugged extensively and found that Objects contained in Objects added to the array where nil. EDIT2:现在可以不保留地运行,我想我知道为什么:我进行了广泛的调试,发现Objects中包含的Object添加到了nil数组中。 Particularly, deep down in encodeWithCoder I did not use "self" when assigning values. 特别是,在encodeWithCoder的最深处,我在分配值时没有使用“ self”。 When decoding, those values where nil. 解码时,这些值为零。 Since I changed that, it seems to work. 自从我更改了它之后,它似乎起作用了。 I suspect that not assigning the new array caused the crash, but the TableView which would read the new array-even before I call reloadData. 怀疑没有分配新数组会导致崩溃,但是TableView甚至在我调用reloadData之前都会读取新数组。 Which would lead back to Davids question of synchroneous access. 这将导致Davids同步访问的问题。 Thank you all for your help. 谢谢大家的帮助。

  1. The code you've shown it appears correct; 您显示的代码看起来正确; it should not be necessary (or correct) to call retain yourself, as long as you are assigning the value to a property with retain semantics before the autorelease pool is drained. 只要您在耗尽自动释放池之前,将值分配给具有retain语义的属性,就不必(或正确)调用自己retain Are all the calls (getDocumentListSortedByDate, getDocumentList) happening synchronously, or are you doing any of this in the background? 所有的调用(getDocumentListSortedByDate,getDocumentList)是同步发生的,还是您在后台执行这些操作? Double-check that you're assigning using the "self." 仔细检查您要使用“自我”进行分配。 ("self.documentListArray =") instead of just assigning directly to the instance var ("documentListArray ="); (“ self.documentListArray =”),而不仅仅是直接分配给实例var(“ documentListArray =”); if you omit the "self.", the setter is bypassed. 如果省略“自我”,则将忽略设置器。

  2. No, don't free the old value before assigning; 不,在分配之前不要释放旧值; that's the setter's job. 那是安装员的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM