iOS 内存管理问题

发布于 2024-12-29 09:46:29 字数 694 浏览 2 评论 0原文

当您使用 Xcode 的功能并将 nib 文件拖到 .h 和 .m 文件中时,Xcode 会在 deallocviewDidUnload 中添加代码。它添加了我通常不添加的额外代码。我只是好奇是否需要这个额外的代码。

我会做[self setDisplaySlider:nil],而不是disp = nil[disp release]

有这个必要吗?我认为你不必释放 disp.

@interface ViewController : UIViewController
{
   IBOutlet UISegmentedControl *disp;    
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

- (void)viewDidUnload
{
    [self setDisplaySlider:nil];
    [disp release];
    disp = nil;
    [super viewDidUnload];
}

- (void)dealloc {
    [displaySlider release];
    [disp release];
    [super dealloc];
}

When you use Xcode's feature and drag from the nib file into the .h and .m file, Xcode adds the code in the dealloc and viewDidUnload. It adds extra code I do not normally add. I am just curious if this extra code is needed.

I would have done [self setDisplaySlider:nil] and not disp = nil and [disp release].

Is this necessary? I don't think you have to release disp.

@interface ViewController : UIViewController
{
   IBOutlet UISegmentedControl *disp;    
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

- (void)viewDidUnload
{
    [self setDisplaySlider:nil];
    [disp release];
    disp = nil;
    [super viewDidUnload];
}

- (void)dealloc {
    [displaySlider release];
    [disp release];
    [super dealloc];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就是爱搞怪 2025-01-05 09:46:29

在我看来,您提供了一个带有额外代码的类。我会尝试解释一下。

首先,在之前的内容中,您有两个不同的 IBOutlet。我认为第一个是您添加的。

IBOutlet UISegmentedControl *disp;

相反,第二个是在您进行拖放操作时由 Xcode 添加的。

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

首先考虑

术语IBOutlet 只是 Xcode 的占位符。通过它,Xcode 可以帮助您将实例变量连接到图形元素。

当我使用插座连接时,我通常提供像 @property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider; 这样的访问器(如 Xcode 所做的那样),因为如果不提供,可能会出现内存泄漏问题。

第二个考虑因素

Xcode提供的代码是正确的。当您进行拖动操作时,您将 displayController 实例变量与图形元素链接在一起。为了平衡此连接,必须在 dealloc 方法中释放该实例变量,如下所示:

[displayController release];

令人上瘾的是,Xcode 添加了 [self setDisplaySlider:nil]; 因为在内存警告情况下 viewDidUnload 方法可以被调用。这里没有问题,因为当控制器再次加载到内存中时,插座连接将恢复。

两个方法调用之间的区别可以在 高级内存管理文档release-or-set-to-nil-retained-members。请注意,如果您这样做:

[displayController release];

您将直接访问名为 displayController 的实例变量,而如果您这样做:

[self setDisplaySlider:nil]; // or self.displaySlider = nil;

您将访问该实例变量的访问器(在本例中为 setter 方法)。它不一样(为了避免混淆,请参阅我提供的代码)。

所以,这是我将使用的代码(我添加了一些注释来指导您):

//.h
@interface ViewController : UIViewController
{
    UISegmentedControl *disp; // instance variable called disp
    // (A) now this is no longer necessary, new compile mechanism will create an instance
    // variable called _displaySlider under the hood
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

//.m
@synthesize displaySlider = disp;  // I say to Xcode to create a setter and a getter to access the instance variable called disp as written in @property directive
// no longer necessary for (A)

- (void)viewDidUnload
{
    [super viewDidUnload];        
    [self setDisplaySlider:nil]; // I call the setter method to release the UISegmentedControl
}

- (void)dealloc {
    [disp release]; // I release the UISegmentedControl directly
    // if you choose the (A) mechanism simply do
    // [_displaySlider release];
    [super dealloc];
}

希望它有所帮助。

In my opinion you provided a class with extra code. I'll try to explain.

First of all, in your previous you have two different IBOutlet. I think that the first one has been added by you.

IBOutlet UISegmentedControl *disp;

The second one, instead, has been added by Xcode when you made the drag and drop oeration.

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

First consideration

The term IBOutlet is only a placeholder for Xcode. By means of it, Xcode helps you to connect an instance variable to a graphical element.

When I use outlet connections I usually supplying an accessor like @property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider; (as Xcode did) because if not you could incurr in memory leak problems.

Second consideration

The code Xcode has provided is right. When you made the drag operation you linked toghether displayController instance variable with your graphical element. To balance this connection, that instance variable has to be released in dealloc method like the following:

[displayController release];

In addiction, Xcode added [self setDisplaySlider:nil]; because in memory warning situations viewDidUnload method could be called. No problem here because whene the controller is loaded in memory again, the outlet connection is restored.

The difference between the two method calls can be read in Advanced Memory Management doc and release-or-set-to-nil-retained-members. Note that if you do this:

[displayController release];

you access directly your instance variable called displayController, while if you do this:

[self setDisplaySlider:nil]; // or self.displaySlider = nil;

you access the accessor (the setter method in this case) for that instance variable. It's not the same (to avoid confusion see the code I provided).

So, this is the code I would use (I added some comments to guide you):

//.h
@interface ViewController : UIViewController
{
    UISegmentedControl *disp; // instance variable called disp
    // (A) now this is no longer necessary, new compile mechanism will create an instance
    // variable called _displaySlider under the hood
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

//.m
@synthesize displaySlider = disp;  // I say to Xcode to create a setter and a getter to access the instance variable called disp as written in @property directive
// no longer necessary for (A)

- (void)viewDidUnload
{
    [super viewDidUnload];        
    [self setDisplaySlider:nil]; // I call the setter method to release the UISegmentedControl
}

- (void)dealloc {
    [disp release]; // I release the UISegmentedControl directly
    // if you choose the (A) mechanism simply do
    // [_displaySlider release];
    [super dealloc];
}

Hope it helps.

往昔成烟 2025-01-05 09:46:29

看看你的 viewDidLoad: 我想你会发现对象正在那里分配。

您需要通过 viewDidUnload 中的释放来平衡这一点,否则如果视图再次加载,对象将在没有释放的情况下再次分配,并且您将发生泄漏。

Have a look at your viewDidLoad: I think you'll find that the objects are being allocated there.

You need to balance this with releases in viewDidUnload, otherwise if the view gets loaded again, the objects will be allocated again without having been released, and you'll be leaking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文