首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么会对iPhone的记忆管理不善呢?

我怎么会对iPhone的记忆管理不善呢?
EN

Stack Overflow用户
提问于 2009-09-01 08:15:32
回答 2查看 807关注 0票数 1

此代码适用于:

monkey.h

代码语言:javascript
复制
@interface monkey : NSObject {
NSNumber *monkeyRanch;
}
@property (nonatomic, retain) NSNumber *monkeyRanch;
-(id) gatherTheMonkeys:(int)howmany;

monkey.m

代码语言:javascript
复制
@synthesize monkeyRanch;
-(id) gatherTheMonkeys:(int)howmany{
NSNumber *temp=[[NSNumber alloc] initWithInt:howmany];
monkeyRanch = temp;
[temp release];
return [monkeyRanch autorelease];
}

appDelegate.m

代码语言:javascript
复制
theMonkeys = [[monkey alloc] gatherTheMonkeys:3];
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];

..and theMonkeys在dealloc中释放。仪器没有漏水。但是,如果我对NSMutable数组而不是NSNumber进行同样的尝试

monkey.h

代码语言:javascript
复制
@interface monkey : NSObject {
    NSMutableArray *monkeyRanch;
}
@property (nonatomic, retain) NSMutableArray *monkeyRanch;
-(id) initTheMonkeys:(int)howmany;

monkey.m @合成monkeyRanch;

代码语言:javascript
复制
-(id) initTheMonkeys:(int)howmany{
monkeyRanch=[[NSMutableArray alloc] init];
NSNumber *imp =[[NSNumber alloc] initWithInteger:howmany];
[monkeyRanch addObject:imp];
[imp release];
return [monkeyRanch autorelease];
}

appDelegate

代码语言:javascript
复制
theMonkeys = [[monkey alloc] initTheMonkeys:3];
[theMonkeys retain];

这会导致(对象‘猴子’)在应用程序开始时泄漏。

我试图将initTheMonkeys更改为:

代码语言:javascript
复制
NSMutableArray *temp=[[NSMutableArray alloc] init];
monkeyRanch=temp;
[temp release];
NSNumber *imp =[[NSNumber alloc] initWithInteger:howmany];
[monkeyRanch addObject:imp];
[imp release];
return [monkeyRanch autorelease];

但是monkeyRanch的保留数在发布临时程序时下降到零,应用程序很高兴地崩溃了。

我做错了什么,我该怎么补救?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-01 08:39:26

你的记忆问题归结为所有权问题。当类有实例变量(如monkeyRanch)时,通常在该类的初始化器中创建一个实例,然后在dealloc中释放它,如下所示:

代码语言:javascript
复制
@interface Monkey : NSObject {
    NSMutableArray * monkeyRanch;
}
@end

@implementation Monkey
- (id)init {
    if ((self = [super init]) == nil) { return nil; }
    monkeyRanch = [[NSMutableArray alloc] initWithCapacity:0];
    return self;
}
- (void)dealloc {
    [monkeyRanch release];
}
@end

在本例中,Monkey类拥有monkeyRanch成员。

在函数调用中,必须确保release initretaincopy中的任何本地对象。看起来这部分是正确的,但我还是会给出一个简单的例子:

代码语言:javascript
复制
- (void)someFunction {
    NSNumber * myNumber = [[NSNumber alloc] init];
    ...
    [myNumber release];
}

接下来要理解的是,简单地设置一个成员变量和设置一个属性值是有很大区别的。这就是说:

代码语言:javascript
复制
NSMutableArray * temp = [[NSMutableArray alloc] initWithCapacity:0];
monkeyRanch = temp;
[temp release]; // it's gone!

不是一回事:

代码语言:javascript
复制
NSMutableArray * temp = [[NSMutableArray alloc] initWithCapacity:0];
self.monkeyRanch = temp; // now owned by self
[temp release];

在第一种情况下,您只需设置一个指针(monkeyRanch)等于另一个指针(temp)。该值不被保留或复制。

在第二种情况下,您实际上是在设置属性。这意味着,假设属性被设置为object,数组现在由类对象拥有。

P.S.:

你也可能在设计上走错了轨道。在我看来,猴子牧场里有很多猴子。如果是这样的话,那么您的Monkey对象就不应该拥有MonkeyRanch。相反,我会做这样的事情:

Monkey.h

代码语言:javascript
复制
@class MonkeyRanch;

@interface Monkey : NSObject {
    MonkeyRanch * ranch;
}
@property (nonatomic, assign) MonkeyRanch * ranch;
@end

Monkey.m

代码语言:javascript
复制
@implementation Monkey
@synthesize ranch;
@end

MonkeyRanch.h

代码语言:javascript
复制
#import "Monkey.h"

@interface MonkeyRanch : NSObject {
    NSMutableArray * monkeys;
}
@property (nonatomic, retain) NSMutableArray * monkeys;
- (id)initWithNumberOfMonkeys:(int)howMany;
- (void)dealloc;
@end

MonkeyRanch.m

代码语言:javascript
复制
@implementation MonkeyRanch

@synthesize monkeys;

- (id)initWithNumberOfMonkeys:(int)howMany {
    if ((self = [super init]) == nil) { return nil; }

    monkeys = [[NSMutableArray alloc] initWithCapacity:howMany];
    for (int index = 0; index < howMany; index++) {
        Monkey * newMonkey = [[Monkey alloc] init];
        [newMonkey setRanch:self];
        [monkeys addObject:newMonkey];
        [newMonkey release];
    }

    return self;
}

- (void)dealloc {
    [monkeys release];
}

@end

使用:

代码语言:javascript
复制
#import "MonkeyRanch.h"

MonkeyRanch * theRanch = [[MonkeyRanch alloc] initWithNumberOfMonkeys:3];

...

[theRanch release];
票数 3
EN

Stack Overflow用户

发布于 2009-09-01 08:36:09

实际上,你错过了这个:

代码语言:javascript
复制
theMonkeys = [[monkey alloc] initTheMonkeys:3];
[theMonkeys retain];

当你“插入”某物时,你会得到一个隐含的“保留”(保留计数是1)。这是你的漏洞,你既在它里面,又保留它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1361194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档