Objective c 目标C指针?
我是新的编码,并试图与Objective-C的速度。 遇到一些我不懂的代码。我希望有人能 给我澄清一下。在下面的例子中,我不确定*foo2是如何工作的,为什么不发布它Objective c 目标C指针?,objective-c,oop,pointers,Objective C,Oop,Pointers,我是新的编码,并试图与Objective-C的速度。 遇到一些我不懂的代码。我希望有人能 给我澄清一下。在下面的例子中,我不确定*foo2是如何工作的,为什么不发布它 ClassOne *pointer = [[ClassOne alloc]init]; ClassTwo *foo = [[ClassTwo alloc]init], *foo2; foo2 = [foo add: pointer]; [foo release]; foo = foo2 [pointer relea
ClassOne *pointer = [[ClassOne alloc]init];
ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
foo2 = [foo add: pointer];
[foo release];
foo = foo2
[pointer release];
[foo release];
因为你还没有发布。您在这里释放引用,而不是释放指针。这不完全是一回事。当您第二次执行[foo release]时,您正在释放在将foo2分配给foo时创建的foo引用 要发布foo2引用,您需要实际调用该引用的release,而不是引用的副本
ClassOne *pointer = [[ClassOne alloc]init];
变量pointer
是指向class One对象的指针。它为新创建的对象指定了值
ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
*foo
和*foo2
是类ClassTwo
的对象。只有foo
被分配了一个新创建的对象foo2
可能指向任何东西,因此在为其赋值之前使用它是不安全的
foo2 = [foo add: pointer];
foo2
被分配了一个值:我假设classClassTwo
的add:
消息创建了一个对象(方法的签名应该是-(ClassTwo*)add:(ClassOne*);
)
不再需要foo
指向的对象
foo = foo2;
[foo release];
变量foo
被赋予foo2
的值:两者都指向同一对象
[pointer release];
不再需要指针指向的对象
foo = foo2;
[foo release];
不再需要foo
(以及foo2
)所指向的对象。从您的简单示例中,很难说出发生了什么。通常,[class add:]类型方法返回void,因此它们应该发出编译器警告,“void值不会像应该的那样被忽略。”
foo = foo2;
[foo release];
因此,如果没有更多的信息,就有点难搞清楚
需要记住的几件事:
- 您可以在objc中将命令发送到“nil”。因此,如果[foo add:pointer]返回nil,那么您可以整天对其调用“release”,而不会产生任何影响
- 重新计数是你的朋友。您可以在任何NSObject上调用它,以查看有多少对象固定在它上面。这也可能有助于您追踪问题
- 最后,垃圾收集是否已启动
这取决于什么
[foo add:pointer]代码>可以。它看起来像是返回了foo
的副本并保留了它。这显然是一个糟糕的设计,因为如果返回的对象是副本/引用,那么从方法上看应该很明显。名为add:
的方法不应返回副本
逐步:
// this somehow creates a retained copy of foo.
foo2 = [foo add:pointer];
// foo is released and gets destroyed.
[foo release];
// makes foo point to the same object as foo2
// (`foo` has no connection to the former object anymore)
foo = foo2;
// foo (and foo2 as they point to the same object) are released
[foo release];
你真正想关注的是指针是如何工作的。我想你还没有理解指针和对象之间的区别
.对于Objective-C Cocoa,我们正在使用半自动引用计数内存管理。为对象分配内存、保留对象或对对象调用copy
方法时,保留计数(引用计数)递增1。在对象上调用release
时,它会将保留计数减一。在对象上调用autorelease
时,将在将来的某个时间点对该对象调用release
(在主运行循环期间,当您自己的代码都没有执行时,因此当您尝试使用它时,它不会从您下方拉出引用)。当保留计数达到0时,可以取消分配对象
通常,如果您对某个对象调用retain
,则表示您对该对象感兴趣,并负责在您对该对象不再感兴趣的某个时间点调用release
或autorelease
。同样,如果在对象上调用alloc
或copy
方法,则表示您对该对象感兴趣,并且必须将其与release
或autorelease
匹配
此链接几乎涵盖了苹果用于(以及您应该使用)内存管理的指导原则:
让我们逐行检查代码:
指针
指向一个新分配的ClassOne对象,保留计数为1,因为我们对它调用了alloc。我们有责任在将来的某个时候调用指针上的释放
或自动释放
foo
指向一个新分配的ClassTwo对象,retain计数为1,因为我们对它调用了alloc。我们有责任在将来的某个时候在foo
上调用release
或autorelease
foo2
目前没有指向任何特定的内容。使用起来不安全
指针
已添加到foo
(不管这意味着什么,我们不知道具体实现)foo
可能调用pointer
上的retain
来表示它对它感兴趣,并将它添加为字段,或者它可能已将pointer
添加到集合中(在这种情况下,集合有责任在添加对象时调用retain
,在移除对象时调用release
)。在任何情况下,它都不会影响我们的代码块,因此我们不关心引擎盖下发生了什么
此方法返回的引用可能是指针
本身,也可能是指针
的自动删除副本;我们无法访问API或实现来告诉我们是哪个
在任何一种情况下,我们都不负责对此对象调用release
。如果该方法的名称中包含copy
,或者如果我们对返回的引用调用了retain
(例如foo2=[[foo-add:pointer]retain];
),则保留计数将增加1,我们有责任调用release
或autorelea
[foo release];
foo = foo2;
[pointer release];
[foo release];