1

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

我的类.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

我的班级.m

#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

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

更新 1

@synthesize 添加,见上文。

更新 2

没有把它放到另一个帖子中,因为这似乎是相当相关的问题:

见上面MyClass.m/.h,有一个私有的ivar(这里不知道应该叫ivar还是字段)UIImageView *imageView;,它没有属性,没有@synthesize,那里给出了初始化,我们怎样才能dealloc呢?也在? [imageView release];_-(void)dealloc

更新 3

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

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

3 回答 3

1

是的。你需要实现dealloc。

你 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;
于 2013-10-29T08:48:49.460 回答
1

由于您没有使用 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
于 2013-10-29T09:25:53.597 回答
1

虽然丹尼尔的回答在解决您的问题时是正确的,但它并未涵盖您应该做什么。

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

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

  • 不要使用@synthesize 也不要声明 iVars(当然也不要在 .h 文件中声明 iVars)。让编译器_自动合成前缀 ivars。前缀还有一个额外的_好处,就是不允许您意外地直接访问代码中的 ivar。即self.foofoo; 第二个不会编译。

或者翻译成代码:

@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

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


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

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

 @property(nonatomic, retain) UIImageView *imageView;

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


在 dealloc 方法中释放它之前,我们是否必须确保 ivar 不是 nil ?(见上面的更新 3。)

不,在 Objective-C 中,nil 吃掉了 messages。也就是说,[nil release];它是完全有效的,并且在运行时绝对不做任何事情。


在您的代码中,BOOL 标志;已经消失了。我们是否为 BOOL 标志创建了一个属性;即@property BOOL 标志;?或者我们所要做的只是在 MyClass.h 中放置一个私有字段作为 @private BOOL 标志;在我原来的问题中?

我忘记了。您可以为它创建一个属性。或者你可以像我上面所做的那样声明_flag为 iVar 。_imageView

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

于 2013-10-29T14:54:53.547 回答