我是Objective-C编程的新手,在尝试在方法中创建对象时遇到了一些麻烦。该程序的目的是提供一种表示有向图的方法,我将在稍后用于测试图论。
问题。
//From GraphObject.m
-(void) addNode
{
GraphNode *newNode = [[GraphNode alloc] initWithId:count];
[graphNodes addObject:newNode];
NSLog(@"Node %i added", count);
count++;
}
这段摘录来自我的GraphObject类,是程序中断的地方。它打破了块中的第一行。 此方法用于创建GraphNode对象并将其放在GraphObject类的NSMutableArray(名为graphNodes)中。 count变量只是跟踪已添加的节点数。 习惯于C ++我很难理解为什么它不会把对象放在堆上,让我使用它。顺便说一句。如果我把它放在我的主要部分中,那么完全相同的线就能正常工作,这会让我有点失望。
如果有人能解释我做错了什么,我们将不胜感激。
编辑: 这是initWithId方法。我开始怀疑原因可能在这里。是否必须返回指向self的指针?
-(id) initWithId:(int)n
{
nodeId = [NSNumber numberWithInt:n];
neighbourNodes = [NSMutableArray arrayWithCapacity:8];
return self;
}
你提到的内存泄漏(yAak),我假设它是关于在这个方法中创建GraphNode数组。但是当我删除我放入的数组时,这不会解决吗?如果我用相同的方法删除它们,就我看来,没有任何东西会被放入数组中。此外,我很抱歉没有发布任何错误消息,因为我是xcode的新手,但我根本看不到任何错误消息。构建是成功的,它只是简单地说程序停在代码中的某一行。
EDIT2(和解决方案):嗯,这是一个奇怪的惊喜。我删除/剪切代码并运行程序一次,然后将完全相同的代码粘贴回来,现在工作正常。那是一个稳定的IDE。再次感谢回复,我相信我很快就会回到这里。
答案 0 :(得分:2)
您的初始化程序:
-(id) initWithId:(int)n
{
nodeId = [NSNumber numberWithInt:n];
neighbourNodes = [NSMutableArray arrayWithCapacity:8];
return self;
}
应如下所示:
- (id)initWithId:(int)n
{
self = [super init]; /* << or whatever the designated initializer of the superclass is */
if (nil != self) {
nodeId = [[NSNumber alloc] initWithInt:n];
neighbourNodes = [[NSMutableArray alloc] initWithCapacity:8];
}
return self;
}
就堆而言,您创建的每个NSObject实例都是在堆上引用计数的。 Clang甚至不允许你在堆栈上制作objc对象(GCC会)。
当你认为你的堆乱了或你的对象或其成员过早地被释放时,请记住有一堆内存/引用计数诊断工具:僵尸是一个,GuardMalloc和涂鸦是其他人。当然,泄漏也是一个很好的检查。
答案 1 :(得分:0)
泄漏,NSZombies等都是有用的工具。但是当esp。当你是这门语言的新手时(有时即使你不熟悉),解决这类内存管理问题的最佳方法是:
2)再次查看你的代码。
[...等]
在这种情况下,由于您没有获得NSNumber对象的所有权,因此在应用程序的运行循环的下一个循环之前将其取消分配。
这在main中没有发生,因为你在应用程序的runloop之外并且没有自动释放池(你可能有一个控制台消息说该对象泄漏,因为没有自动释放池)。如果您不确定是什么,请阅读链接文档中有关自动释放池的部分。