这段代码可以在没有被覆盖的 dealloc 方法 (Objective-C) 的情况下工作吗?



使用手动内存管理。以下代码运行良好,不会发生崩溃。但是没有-(void)dealloc方法。这段代码有错吗?我应该添加-(void)dealloc吗?

MyClass.h

#import <UIKit/UIKit.h>
@interface MyClass : NSObject {
    @private
        BOOL flag;
        UIView *view;
        UILabel *label;
        UIButton *button;
        UITabBar *tabBar;
        UIWebView *webView;
        UIImageView *imageView;
}
@property (nonatomic, retain) UIView *view;
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) UIButton *button;
@property (nonatomic, retain) UITabBar *tabBar;
@property (nonatomic, retain) UIWebView *webView;
@end

我的班级

#import "MyClass.h"
@implementation MyClass
@synthesize view;
@synthesize label;
@synthesize button;
@synthesize tabBar;
@synthesize webView;
- (id)init {
    self = [super init];
    if (self) {
        // Initialization code            
        // Among other code,
        imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    }
    return self;
}
// Other methods here.
// But -(void)dealloc is not overridden here in the MyClass.m
@end

如果我们必须为上面的代码添加-(void)dealloc,它应该是这样的:

被覆盖 -(无效)交易

-(void)dealloc {
    [view release];
    [label release];
    [button release];
    [tabBar release];
    [webView release];
    [super dealloc];
}

更新 1

@synthesize添加,见上文。

更新 2

没有把它放到另一篇文章中,因为这似乎是相当相关的问题:

看到上面的MyClass.m/.h,有一个私有的ivar(不确定这里应该叫ivar或field)UIImageView *imageView;,它没有属性,没有@synthesize,初始化在那里给出,我们怎么解散它?还[imageView release]; -(void)dealloc

更新 3

在发布ivar之前,我们必须检查可用性吗?也就是说,而不是 [view release]; ,使用这个:

if (nil != view) {
    [view release];
}

是的。您需要实现 dealloc。

您的交易位置将如下所示:

-(void)dealloc {
    [_view release];
    [_label release];
    [_button release];
    [_tabBar release];
    [_webView release];
    [super dealloc];
}

任何保留/复制的属性都应在 dealloc 上释放。

你的iVar没有任何意义。它们与属性的信息不同,因此您可以删除 iVar。

如果您希望您的属性由您的 iVar 备份,您应该像这样@synthesize它们:

@synthesize view = view;
@synthesize label = label;
@synthesize button = button;
@synthesize tabBar = tabBar;
@synthesize webView = webView;

由于您没有使用 ARC,因此您的代码(包括 dealloc 方法)是正确的,但是您在实现中缺少 @synthesize 语句以使属性正常工作:

    @implementation MyClass
    // this will synthesize the getters and setters
    @synthesize view, label, button, tabBar, webView;
    - (id)init {
        self = [super init];
        if (self) {
            // Initialization code            
        }
        return self;
    }
    // Other methods here.
   -(void)dealloc {
     [view release];
     [label release];
     [button release];
     [tabBar release];
     [webView release];
     [super dealloc];
   } 

   @end

虽然丹尼尔的回答在回答你的问题时是正确的,但它并没有涵盖你应该做什么。

这就是在现代世界中编写代码的方式:

  • 打开 ARC。 特别是如果您正在学习或这是您的第一个项目。 没有理由不使用 ARC。 学习手动保留发布很有价值,但目前并不重要,因为这些工具在分析基于 ARC 的模式何时泄漏内存方面做得很好(分析器或使用仪器,两者都需要在 MRR 下使用,而在 MRR 下两者都不能很好地工作)。

  • 不要使用 @synthesize,也不要声明 iVars
  • (当然也不要在 .h 文件中声明 iVars)。 让编译器自动合成_前缀的 ivar。 _前缀的另一个优点是不允许你意外地直接访问代码中的 ivar。 即 self.foo vs. foo ; 第二个不会编译。

或者翻译成代码:

@interface MyClass : NSObject
@property (nonatomic, retain) UIView *view;
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) UIButton *button;
@property (nonatomic, retain) UITabBar *tabBar;
@property (nonatomic, retain) UIWebView *webView;
@end

和:

@implementation MyClass
{
    BOOL _flag;
    UIImageView *_imageView;
}
- (id)init {
    self = [super init];
    if (self) {
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    }
    return self;
}
// no -dealloc    
@end

请注意,我将 _imageView 声明为一个实例变量,如果您稍后需要重构类以使其在外部可用,该变量将与明显的imageView @property兼容。

如果您确实必须使用手动保留-释放,则添加一个在所有 ivar 上调用 -release-dealloc方法。 即[_view release];[_imageView release];等...


不明白你的意思是"请注意,我宣布_imageView为 将与明显的图像兼容的实例变量查看 @property以后是否需要重构类才能做到这一点 外部可用。

如果您决定其他对象需要访问_imageView,则可以删除 iVar 声明并添加:

 @property(nonatomic, retain) UIImageView *imageView;

编译器自动合成将自动创建一个名为 _imageView 的实例变量,其余代码都不必更改。


我们是否必须确保 ivar 不是零,然后再将其释放到 交易方法?(请参阅上面的更新 3。

不。 在 Objective-C 中,nil 吃消息。 也就是说,[nil release]; 是完全有效的,并且在运行时绝对不执行任何操作。


在您的代码中,BOOL 标志 ; 已消失。我们是否做了一个 布尔标志的属性;,即@property布尔标志;?或者我们所拥有的一切 只需在MyClass.h中放置一个私有字段作为@private 布尔旗;在我最初的问题中?

我忘了。 您可以为其创建一个属性。 或者你可以像我上面所做的那样,在_imageView旁边将_flag声明为 iVar。

最重要的是,不再有任何理由(除了通常避免的极少数情况)在.h中声明实例变量。

最新更新