1

手動のメモリ管理が使用されます。次のコードは正常に実行され、クラッシュは発生しません。しかし、-(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

MyClass.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、そこに初期化が指定されています。また[imageView release];-(void)dealloc

アップデート 3

ivar をリリースする前に、可用性を確認する必要がありますか? つまり、 の代わりに[view release];、これを使用します。

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

3 に答える 3

1

ダニエルの答えはあなたの質問に答える上で正しいですが、何をすべきかについては触れていません。

これは、現代の世界でコードを記述する方法です。

  • ARCをオンにします。特に学習中の場合、またはこれが最初のプロジェクトである場合。ARC を使用しない理由はありません。manual-retain-release を学習することは価値がありますが、ツールは ARC ベースのパターンがメモリをリークしている場合 (アナライザーまたはインストゥルメントのいずれかを使用する必要があります。どちらも使用する必要があります) を分析するのに非常に優れているため、現時点では重要ではありません。 MRR の下で、どちらも MRR の下ではうまく機能しません)。

  • @synthesize を使用せず、iVar を宣言しないでください (もちろん、.h ファイルで iVar を宣言しないでください)。_コンパイラーがプレフィックス付き ivar を自動的に自動合成できるようにします。_プレフィックスには、コード内の ivar に誤って直接アクセスすることを防ぐという追加の利点があります。すなわちself.foofoo。2番目はコンパイルされません。

またはコードに変換するには:

@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-deallocを呼び出すメソッドを追加します。つまり、、、など...-release[_view release];[_imageView release];


「後でクラスをリファクタリングして外部から利用できるようにする必要がある場合に備えて、明らかな imageView @property と互換性のあるインスタンス変数として _imageView を宣言したことに注意してください。」

他のオブジェクトからアクセスできるようにする必要があると判断した場合_imageViewは、iVar 宣言を削除して次を追加します。

 @property(nonatomic, retain) UIImageView *imageView;

コンパイラの自動合成は、自動的に名前が付けられたインスタンス変数を作成し_imageView、残りのコードを変更する必要はありません。


dealloc メソッドで ivar を解放する前に、ivar が nil でないことを確認する必要がありますか? (上記の更新 3 を参照してください。)

いいえ。Objective-C では、nil はメッセージを食べます。つまり、[nil release];完全に有効で、実行時に何もしません。


あなたのコードでは BOOL フラグ。消えました。BOOL フラグ、つまり @property BOOL フラグのプロパティを作成する必要がありますか? または、MyClass.h にプライベート フィールドを @private BOOL フラグとして配置するだけです。私の元の質問にそこまで?

忘れました。そのためのプロパティを作成できます。または、上記で行ったように_flag、次の iVar として宣言することもできます。_imageView

最も重要なことは、.h.

于 2013-10-29T14:54:53.547 に答える
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 に答える