声明,分配,加载和释放NSMutableArray的正确方法

Bon*_*nie 6 iphone objective-c nsmutablearray dealloc

我在我的*.h文件中声明我的数组:

@interface aViewController: UIViewController
{
   NSMutableArray *anArray;    // You will need to later change this many times.
}
@end

我为它的*.m文件分配内存:

-(void) viewDidLoad
{
   anArray = [[NSMutableArray alloc] init];
}

我单击一个测试按钮来加载我的数组(最终它需要在每次点击时加载DIFFERNT值):

   anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];

我在这里释放它:

-(void) dealloc
{
   [anArray release];
   [super dealloc];
}

这一切看起来都不错吗?

因为我以后运行此代码时崩溃:

   NSLog(@"%d", [anArray count]);

不知道为什么一个简单的"NSLog()和count"会使一切崩溃.


短剑,

让我这样说吧:我对指针,数组,字符串和内存有很大的误解.

我已经阅读了我能在其上找到的所有内容......但是(还)要找到一个简单,清晰,易于理解的描述.

你能建议吗?(希望小于10页的阅读.)是否有解释的参考JUST这个话题:"你有12年以上的编码经验有史以来处理分配内存或指针......但没有" ......从的角度来看. )

所以变量名不是我引用对象的方式吗?那为什么呢?

我已经习惯了许多其他语言:

myString = "this"
myString = "that"

myInt = 5
myInt = 15

(什么可以更简单.)


在我看来这样做是最简单的方法.(而且它似乎有效.但这是真的正确吗?)

Don't alloc any memory for my NSMutableArray initially.
Don't re-alloc any memory repeatedly.  (When I change my array's values.)
Don't release it repeatedly. (Before I change my array's values.)
Don't release it when I exit the program.

But:
Always remember to use RETAIN when I initially assign 
(and repeatedly reassign) new values to my anArray variable.

你没有用anArray = [NSMutableArray arrayWithObjects:@"one",@"two",@"three",nil]加载你的数组; 相反,您正在用新实例替换它,更糟糕的是:对于一个实例,其引用实际上由您无法控制的某个实体拥有

哇.所以我可以拥有20个数组......所有的名字都叫同一个名字:anArray ......它们会有所不同吗?(没有GLOBAL数组这样的东西?)

为了清除旧值,方法removeAllObject可能很方便.还有一些变异方法,可用于一次添加多个值.

所以......首先我必须"删除所有对象"......然后我可以调用ONE方法重新添加所有新值.

anArray = [[NSMutableArray arrayWithObjects:@"one",@"two",@"three",nil] retain]; 而不是alloc/init序列.

哇.我认为没有任何东西可以存储在数组中而不为它分配空间.

如果您真的打算替换整个数组,可能需要考虑使用属性

我如何使用属性?
做这样的事情的正确方法是什么:

> anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
> anArray = [NSMutableArray arrayWithObjects:@"four", @"five", @"six", nil];

就像我会这样做:

x = 12;
x = 24;

哇.我真的完全误解了字符串,数组和内存的一切.我认为"简单方法"是分配ONCE ...使用可变数组......根据需要更改它...并释放它.

这样做的问题是不保留这个新数组,

我认为旧阵列将会消失......并且可以使用新阵列.(但我猜不是.)

此外,您有内存泄漏,因为您从未释放原始数组.

我当时认为旧阵列不应该被释放...我没有完成它...我只是想改变它以包含我的新值.(但我猜不是.)

但一个是使用[anArray release];

我在想这会让我释放我分配的内存......(但我猜不是)......然后我必须重新分配更多的内存.(但我猜不是.)

anArray = [[NSMutableArray arrayWithObjects:@"one",@"two",@"three",nil] retain];

所以我必须"保留"它...所以它不会从我身下消失?(不知道为什么会这样.直到告诉它......在我最后的dealloc电话中.)

另一种可能更正确的修复方法是使用addObject:或addObjectsFromArray:NSMutableArray方法,而不是不断创建新数组.

我只想创建一个数组......并且只是按照我的意愿使用它.我从不想添加到阵列.我想将它设置为我的新值.

Dir*_*irk 11

您没有加载数组

anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
Run Code Online (Sandbox Code Playgroud)

相反,你要用一个新实例替换它,更糟糕的是:对于一个实例,它的引用实际上是由你无法控制的某个实体所拥有的(很可能是一个NSAutoreleasePool.)你正确拥有的引用,由你创建的引用

[[NSMutableArray alloc] init]
Run Code Online (Sandbox Code Playgroud)

失去了,将被泄露.

而不是更换整个数组引用的,变异您在您的处置已经是一个,使用例如addObject:

[anArray addObject: @"one"]
[anArray addObject: @"two"]
Run Code Online (Sandbox Code Playgroud)

为了清除旧值,该方法removeAllObject可能很方便.还有一些变异方法,可用于一次添加多个值.

或者,您可以使用已经使用的构造方法分配数组,但要小心保留它.在viewDidLoad

anArray = [[NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil] retain];
Run Code Online (Sandbox Code Playgroud)

而不是alloc/ init序列.

如果您真的打算替换整个数组,您可能需要考虑使用属性而不是手动执行引用计数.