Objective c 当没有dealloc方法时,我是否应该自动释放保留的属性/实例变量

Objective c 当没有dealloc方法时,我是否应该自动释放保留的属性/实例变量,objective-c,memory-management,Objective C,Memory Management,我正在学习记忆管理一段时间。阅读苹果的《内存管理指南》以及其他一些作者的书/博客/文章/帖子 仍然让我困惑的是,我是否应该写: nameOfMySynthesizedProperty = [[NSObject alloc] init]; // version 1 或 在一个示例项目中,使用了手动内存管理,没有dealloc方法,版本1用于所有类属性/ivar。有时一些性能甚至没有合成,但使用了它的吸气剂 这些并没有在我读过的那些教程/指南中教过,但是示例项目进展顺利,没有崩溃 任何人都可以给我

我正在学习记忆管理一段时间。阅读苹果的《内存管理指南》以及其他一些作者的书/博客/文章/帖子

仍然让我困惑的是,我是否应该写:

nameOfMySynthesizedProperty = [[NSObject alloc] init]; // version 1

在一个示例项目中,使用了手动内存管理,没有
dealloc
方法,版本1用于所有类属性/ivar。有时一些性能甚至没有合成,但使用了它的吸气剂

这些并没有在我读过的那些教程/指南中教过,但是示例项目进展顺利,没有崩溃

任何人都可以给我一些光

更新1 在示例项目中使用了手动内存管理

更新2 另一个例子

AppDelegate.h

#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
}
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) UIViewController *viewController;
@end
AppDelegate.m
->
-(BOOL)应用程序中:应用程序使用选项完成启动:
方法,以下哪项对于初始化
self.window.rootViewController
是正确的?(使用手动内存管理。使用Xcode 5。)

版本1

self.window.rootViewController = [[UIViewController alloc] init];
self.viewController = [[[UIViewControllerDrawer alloc]init] autorelease];
self.window.rootViewController = self.viewController;
版本2

self.window.rootViewController = [[[UIViewController alloc] init] autorelease];
self.viewController = [[[UIViewControllerDrawer alloc]init] autorelease];
self.window.rootViewController = self.viewController;
版本3

self.viewController = [[[UIViewControllerDrawer alloc]init] autorelease];
self.window.rootViewController = self.viewController;

这里我知道
window
是一个属性(它的实例变量也被命名为
window
)。但是
window.rootViewController
是一个实例变量吗?实验结果表明,版本3正在运行,版本1和版本2都崩溃。

您在这里有几个不同的问题,我将尝试解决它们

解除锁定 总会有一个dealloc方法,您可能不会覆盖它,但它至少是由NSObject实现的。您几乎总是需要在子类中重写此方法以释放对象IVAR。使用ARC时,您只需将它们设置为nil,但在MRC(如您所拥有的)中,您需要向任何保留或分配的变量发送释放消息

当对象保留计数达到0时,将自动调用dealloc方法

使用自动释放 您发布的代码存在一个问题,即您正在将自动释放对象分配给ivar,并且该对象在自动释放池耗尽(通常是事件循环的开始)后将不再有效

当您不想保留对象,但需要为方法的调用者保留对象时,可以使用自动释放。当一个方法返回一个对象时,该对象应该总是按照自动释放,但这并不意味着你总是需要自己发送自动释放消息。如果要返回的对象在其他位置被自动删除,则可以简单地返回该对象

您alloc init的任何内容的retain计数都将为1,您需要在某个点释放它,否则就会发生泄漏

@综合 您不需要显式地合成属性。编译器将为您合成它们。您必须注意属性是如何声明的(如果您自己执行实现,则需要执行),以了解为属性赋值是否会增加保留计数、复制对象或执行简单赋值。我在您更新的问题中看到,您的意思是执行
self.property=[[[NSObject alloc]init]autorelease]
,因为这些属性被声明为保留。您可以改为执行
\u property=[[NSObject alloc]init]
,这是相当典型的用法。在直接使用ivar之前,您需要了解有关属性的语义(例如,KVO通知不会通过分配给ivar而触发)

ARC与MRC
只是关于MRC和ARC的旁白。很多人认为你应该一直使用ARC(如果你能帮助的话),而不是MRC。您必须了解,不正确地使用ARC可能会导致代码速度显著降低。我见过“ARC”代码,它在循环中对临时值使用隐式强引用,导致大量不必要的retain release调用。理解MRC对于编写好的ARC代码IMO来说是必不可少的,不要让这些人阻止你学习内存管理的细节。

如果你从一个以alloc/init、copy、mutableCopy或new开头的方法获得一个对象实例,你拥有它,并负责在完成后释放它。否则,您不负责发布它。如果你想保留一个不属于你的对象,你必须保留它,然后在处理完后释放它。出于这些规则的目的,自动释放对象与释放对象相同。自动释放的对象将在将来的某个时候释放(大多数情况下是当前运行循环的结束)

在您的问题中,您直接设置了ivar。您不希望ivar指向的对象从您下方消失,因此不应自动释放它。除非所讨论的行在类的
-init
方法中,否则应该使用setter,并在将对象传递给setter之前自动释放该对象(
self.nameOfMySynthesizedProperty=[[[NSObject alloc]init]autorelease];
)。这样,setter(假定属性为
strong
/
retain
处理保留对象的操作,并且如果以后再次将其设置为其他对象,也将处理释放对象的操作


最后,我很欣赏你的学习手册内存管理。我认为Objective-C程序员理解它是很重要的。所以,如果这只是一个学习练习,那么继续学习。然而,对于编写真正的代码,你可能应该使用ARC,这使整个问题基本上没有意义。

你也不应该这样做使用ARC。现在很少有理由使用手动内存管理。(了解ARC如何应用内存管理规则很有用,但直接使用它是个坏主意。)

如果您绝对必须使用手动内存管理,则通常也不应以这种方式直接访问IVAR。除了在
init
dealoc
中,您应该执行以下操作:

self.property = [[[NSObject alloc] init] autorelease];
_property = [[NSObject alloc] init];
init
中,您应该
self.property = [[[NSObject alloc] init] autorelease];
_property = [[NSObject alloc] init];
[_property release];
_property = nil;