当前位置:  开发笔记 > IOS > 正文

Objective-C指针?

如何解决《Objective-C指针?》经验,为你挑选了1个好方法。

我是编码新手并尝试使用Objective-C加快速度.碰到了一些我不明白的代码.我希望有人可以为我澄清一下.在下面的例子中,我不确定*foo2是如何工作的以及为什么它没有被释放?

ClassOne *pointer = [[ClassOne alloc]init];

ClassTwo *foo = [[ClassTwo alloc]init], *foo2; 

 foo2 = [foo add: pointer];
 [foo release]; 
 foo = foo2

[pointer release];

[foo release];

小智.. 22

使用Objective-C Cocoa,我们正在使用半自动引用计数内存管理.为对象分配内存,保留对象或copy在对象上调用方法时,保留计数(引用计数)增加1.当调用release对象时,它会将保留计数减1.在调用autorelease一个对象时,release将来会在某个时刻调用该对象(在主运行循环期间,当你自己的代码都没有执行时,所以它不会从你下面拉出引用,因为你是试图使用它).当保留计数达到0时,可以取消分配对象.

一般来说,如果你正在调用retain某个对象,那么就表明你对它感兴趣,并且当你不再对该对象感兴趣时,你有责任在某个时刻打电话releaseautorelease打电话.同样,如果您在某个对象上调用alloc或使用某个copy方法,则表示您对该对象感兴趣,并且必须将其与该行releaseautorelease某个地方相匹配.

这个链接几乎涵盖了Apple使用(并且你应该使用)内存管理的指导原则:Cocoa中内存管理的 简单规则

让我们逐行完成代码:

ClassOne *pointer = [[ClassOne alloc]init];

pointer指向一个新分配的ClassOne对象,保留计数为1,因为我们在其上调用了alloc.我们有责任致电releaseautoreleasepointer在未来的某一时刻.

ClassTwo *foo = [[ClassTwo alloc]init], *foo2;

foo指向一个新分配的ClassTwo对象,保留计数为1,因为我们在其上调用了alloc.我们有责任致电releaseautoreleasefoo在未来的某一时刻.

foo2现在并没有特别指出任何事情.这是不安全的使用.

foo2 = [foo add: pointer];

pointer已被添加到foo(无论这意味着什么;我们不知道实现). foo可能已经调用retainpointer以通知它的利益在里面,并将其添加为一个字段,或者可能添加pointer到一个集合(在这种情况下,它收集的责任来调用retain它添加一个对象时,和release当一个对象被删除).在任何情况下,它都不会影响我们的代码块,因此我们不关心引擎盖下发生了什么

此方法返回的引用可能是pointer自身,也可能是自动释放的副本pointer; 我们无权访问API或实现告诉我们哪个.

无论哪种情况,我们都有责任呼吁release这个对象.如果方法有copy名称,或者我们已经调用retain了返回的引用(例如foo2 = [[foo add:pointer] retain];),则保留计数将增加1,我们有责任调用releaseautorelease使用它.

[foo release];

引用的对象foo已被释放,这意味着它的保留计数已减少1.对于此示例,这与alloc我们在第2行中进行的调用配对,因此保留计数将降为0,从而使得有foo资格被释放.

但是,一般而言,我们并不关心对象是否已被解除分配; 我们只需要确保我们配对的任何alloc,copyretain电话与相同数量的releaseautorelease来电.如果我们在任何时候注册对象的兴趣,我们有责任释放我们的兴趣,否则我们将有内存泄漏.

 foo = foo2;

foo现在指向引用的同一个对象foo2.记住,当我们得到时,我们没有调用alloc或者copy方法foo2,也没有通过调用注册它的兴趣retain.由于我们没有有责任呼吁releasefoo2,我们没有责任来调用releasefoo.

[pointer release];

pointer保留计数已经减少了1.这可能会使其保留计数为0或者不是,这取决于foo我们添加它时的保留计数.不过,我们并不关心; 我们已经完成了我们的责任pointer,呼吁release它与alloc我们在开始时的电话相匹配.尽管pointer在这次调用之后可能仍然存在,但是我们无法做出这样的假设,并且尝试对之前由指针引用的对象做任何事情都是错误的(尽管我们可以改变pointer为指向别的东西).

[foo release];

如果此代码的作者一直遵循Apple的内存管理约定,那么这是不必要的.我们没有责任去呼吁releasefoo或者foo2(它们指向同一个对象,记住).这不会导致代码中断; 在nil引用上调用任何东西本质上都是一个无操作.但是,它可能会导致任何人审查代码时出现混淆.

现在,此代码的作者可能已经破坏了内存管理约定.他可能已经使该add调用返回了一个副本而pointer没有调用autorelease它,在这种情况下,它使调用者负责调用release它.这是非常糟糕的形式,如果您应该遇到破坏内存管理约定的代码,请记录您使用它的位置以及它如何破坏约定以避免将来出现混淆.



1> 小智..:

使用Objective-C Cocoa,我们正在使用半自动引用计数内存管理.为对象分配内存,保留对象或copy在对象上调用方法时,保留计数(引用计数)增加1.当调用release对象时,它会将保留计数减1.在调用autorelease一个对象时,release将来会在某个时刻调用该对象(在主运行循环期间,当你自己的代码都没有执行时,所以它不会从你下面拉出引用,因为你是试图使用它).当保留计数达到0时,可以取消分配对象.

一般来说,如果你正在调用retain某个对象,那么就表明你对它感兴趣,并且当你不再对该对象感兴趣时,你有责任在某个时刻打电话releaseautorelease打电话.同样,如果您在某个对象上调用alloc或使用某个copy方法,则表示您对该对象感兴趣,并且必须将其与该行releaseautorelease某个地方相匹配.

这个链接几乎涵盖了Apple使用(并且你应该使用)内存管理的指导原则:Cocoa中内存管理的 简单规则

让我们逐行完成代码:

ClassOne *pointer = [[ClassOne alloc]init];

pointer指向一个新分配的ClassOne对象,保留计数为1,因为我们在其上调用了alloc.我们有责任致电releaseautoreleasepointer在未来的某一时刻.

ClassTwo *foo = [[ClassTwo alloc]init], *foo2;

foo指向一个新分配的ClassTwo对象,保留计数为1,因为我们在其上调用了alloc.我们有责任致电releaseautoreleasefoo在未来的某一时刻.

foo2现在并没有特别指出任何事情.这是不安全的使用.

foo2 = [foo add: pointer];

pointer已被添加到foo(无论这意味着什么;我们不知道实现). foo可能已经调用retainpointer以通知它的利益在里面,并将其添加为一个字段,或者可能添加pointer到一个集合(在这种情况下,它收集的责任来调用retain它添加一个对象时,和release当一个对象被删除).在任何情况下,它都不会影响我们的代码块,因此我们不关心引擎盖下发生了什么

此方法返回的引用可能是pointer自身,也可能是自动释放的副本pointer; 我们无权访问API或实现告诉我们哪个.

无论哪种情况,我们都有责任呼吁release这个对象.如果方法有copy名称,或者我们已经调用retain了返回的引用(例如foo2 = [[foo add:pointer] retain];),则保留计数将增加1,我们有责任调用releaseautorelease使用它.

[foo release];

引用的对象foo已被释放,这意味着它的保留计数已减少1.对于此示例,这与alloc我们在第2行中进行的调用配对,因此保留计数将降为0,从而使得有foo资格被释放.

但是,一般而言,我们并不关心对象是否已被解除分配; 我们只需要确保我们配对的任何alloc,copyretain电话与相同数量的releaseautorelease来电.如果我们在任何时候注册对象的兴趣,我们有责任释放我们的兴趣,否则我们将有内存泄漏.

 foo = foo2;

foo现在指向引用的同一个对象foo2.记住,当我们得到时,我们没有调用alloc或者copy方法foo2,也没有通过调用注册它的兴趣retain.由于我们没有有责任呼吁releasefoo2,我们没有责任来调用releasefoo.

[pointer release];

pointer保留计数已经减少了1.这可能会使其保留计数为0或者不是,这取决于foo我们添加它时的保留计数.不过,我们并不关心; 我们已经完成了我们的责任pointer,呼吁release它与alloc我们在开始时的电话相匹配.尽管pointer在这次调用之后可能仍然存在,但是我们无法做出这样的假设,并且尝试对之前由指针引用的对象做任何事情都是错误的(尽管我们可以改变pointer为指向别的东西).

[foo release];

如果此代码的作者一直遵循Apple的内存管理约定,那么这是不必要的.我们没有责任去呼吁releasefoo或者foo2(它们指向同一个对象,记住).这不会导致代码中断; 在nil引用上调用任何东西本质上都是一个无操作.但是,它可能会导致任何人审查代码时出现混淆.

现在,此代码的作者可能已经破坏了内存管理约定.他可能已经使该add调用返回了一个副本而pointer没有调用autorelease它,在这种情况下,它使调用者负责调用release它.这是非常糟糕的形式,如果您应该遇到破坏内存管理约定的代码,请记录您使用它的位置以及它如何破坏约定以避免将来出现混淆.


如果我们遵循内存管理准则,最后的[foo release]可能*会导致崩溃.它被设置为[foo add:pointer]的结果,我们不知道它是否为零.如果它只是零以外的任何东西,程序就会热潮.
推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有