Iphone 学习Obj-C内存管理

Iphone 学习Obj-C内存管理,iphone,objective-c,cocoa,macos,memory-management,Iphone,Objective C,Cocoa,Macos,Memory Management,可能重复: 我有网络开发的背景。我擅长XHTML、CSS、JavaScript、PHP和MySQL,因为我在日常工作中使用了所有这些技术 最近我一直在晚上和周末用Xcode修补Obj-C。我已经为iPhone和Mac OS X编写了代码,但我无法理解内存管理的实用性。我理解高级概念,但不清楚在实现中如何实现。Web开发人员通常不必担心这类事情,所以这对我来说是相当新鲜的 我曾尝试将内存管理添加到我的项目中,但结果通常会失败。对如何学习有什么建议吗?感谢您的建议。由于采用了保留/释放模式,Coc

可能重复:

我有网络开发的背景。我擅长XHTML、CSS、JavaScript、PHP和MySQL,因为我在日常工作中使用了所有这些技术

最近我一直在晚上和周末用Xcode修补Obj-C。我已经为iPhone和Mac OS X编写了代码,但我无法理解内存管理的实用性。我理解高级概念,但不清楚在实现中如何实现。Web开发人员通常不必担心这类事情,所以这对我来说是相当新鲜的


我曾尝试将内存管理添加到我的项目中,但结果通常会失败。对如何学习有什么建议吗?感谢您的建议。

由于采用了保留/释放模式,Cocoa中的内存管理实际上非常简单。从学习指针的概念开始——虽然学习objective-C不需要成为C方面的专家,但理解指针是必不可少的。然后阅读(或其他)指南。如果你需要,写下你应该和不应该保留一个对象的规则,通过一点练习,你应该立刻“得到它”


请记住,您可以打开垃圾收集,而不必太担心内存管理,但我不建议这样做;即使启用了GC,您仍然需要了解幕后的情况。

阅读arul提供的链接。既然您使用的是一种没有垃圾收集的语言(如果您是为iPhone开发的),那么现在是时候开始考虑对象的生命周期了。您实例化的每个对象现在都必须由某人(可能是您)解除分配。内存管理不是一门容易的课程,要掌握它,唯一的方法就是练习。玩分配对象和取消分配对象的游戏。将对象添加到集合时,观察保留计数的增长。查看自动释放池。本质上,您应该知道对象在何时何地被分配和解除分配。在内存有限的系统上(如iphone),您希望对象尽快消失


我的建议是,在开始处理大部分应用程序之前,先花几天时间研究一下内存管理。调试内存问题和处理应用程序逻辑有点麻烦

在链接到的post arul中列出的苹果官方资源之外,还有一些关于这个主题的好文章:




有关调试内存管理问题的帮助:

我使用了来自的内存管理视频培训课程。给了我刚开始时所需要的东西。当我开始有自己的内存管理问题时,它立即带来了好处

经验法则 自动释放 每次您有
[[NSObject alloc]init]
时,您都会将其包装到
自动释放中

// make sure it gets properly released
// autorelease releases the object at a later time.
NSObject *instance = [[[NSObject alloc] init] autorelease];
像这样的事情(记不起术语)总是自动删除的,您也应该创建与此规则对应的类:

NSString *test = [NSString stringWithFormat:@"%i", 4];
保留/释放 如果需要将对象存储的时间长于当前方法,请保留该对象:

[instance retain];
如果您不再需要它或与其他对象交换:

[instance release];
代码中的
保留
量应始终与
释放
量相同

访问器 Objective-C2.0让我们为您声明属性并编写访问器。例如
@property(retain,readwrite)NSString*text看起来像这样:

- (NSString *)text {
    return text; // I don't like calling variables _test
}

- (void)setText:(NSString *)newText {
    [newText retain];
    [text release];
    text = newText;
}
- (id)init {
    if (self = [super init]) {
        [self setText:@"Lorem ipsum dolor sit amet."];
        // …
    }
    return self;
}

- (void)dealloc {
    // make sure text is set to nil and the old value gets released.
    [self setText:nil];
}
初始化/解除锁定 在这些方法中,您应该始终像这样使用
[self-setVariable:…]

- (NSString *)text {
    return text; // I don't like calling variables _test
}

- (void)setText:(NSString *)newText {
    [newText retain];
    [text release];
    text = newText;
}
- (id)init {
    if (self = [super init]) {
        [self setText:@"Lorem ipsum dolor sit amet."];
        // …
    }
    return self;
}

- (void)dealloc {
    // make sure text is set to nil and the old value gets released.
    [self setText:nil];
}
垃圾收集器 使用,如果可以的话,不使用它几乎没有什么好处

这个保留/发布是如何工作的? 每次分配对象1时,
[NSObject alloc]
,保留计数设置为1。如果此计数达到0,则删除对象
[实例保留]
将计数增加1,
[实例释放]
将计数减少1


1
[instance copy]
也会分配一个新实例,因此保留计数也为1。

我经常看到的一个错误是在常规发布时使用自动释放方便调用。这只会给您的生活带来困难,因为这会将问题从调用站点中移除,同时使在大型代码库中隔离问题变得非常困难


这也迫使您从一开始就学习内存管理,这并不有趣,但值得一学,因为您通常可以挽救更多您编写的代码。

还要注意,iPhone操作系统不支持垃圾收集。感谢您提供指向“抱住我,使用我,释放我”文章的指针。这是一个非常好且简单的解释。yar:我已经更改了链接,转到了Internet存档的副本。另一方面,做
[[alloc]init]
,而不是
[[alloc]init]autorelease]
,很容易忘记前者需要的
发布
消息。@Peter我想说,这是一个很容易犯的错误(与“非常简单”相反),但这是一个易学的变化。同样,问题通常是直接的,或者(在泄漏检测和静态分析的情况下)导致问题区域,而不是在初始值设定项中设置断点并跟踪谁创建了什么、在哪里、何时…(另请注意,感谢制作RAM磁盘)