1

私は約 1 週間ほどアプリを開発してきましたが、すべてが正しく行われていることを確認するためにプロファイリングするのに良い時期だと思いました。すべてのオブジェクトが解放されているにもかかわらず、配当額が上がっています。オブジェクトを解放するときは、次のことを行います。

[object release];
object = nil;

私のアプリには、アクセス トークンがあるかどうかに応じて、 myLoginViewControllerまたはを表示するかどうかを決定する初期ビュー コントローラーがあります。TimeLineViewController(私が抱えている問題はLoginViewController/内にあるため、この部分は問題ではありませんSignupViewController)。ログイン コントローラーには 2 つのテキスト フィールドと 2 つのボタンがあり、これらのボタンは sVC をナビゲーション ビュー コントローラーにプッシュするか、ログインを試みます。

奇妙なことdeallocに、ビューとビュー コントローラーでメソッドが呼び出されていますが、メソッドが呼び出された後にメモリが増加します。

SDK バージョン 7.0 Xcode バージョン 5.0

編集:

私の LoginViewController では、LoginView から SignupButton がクリックされたというイベントを取得すると、このメソッドが呼び出されます。

- (void)signupButtonPressed
{
    SignupViewController *signupVC = [[SignupViewController alloc] init];
    [self.navigationController pushViewController:signupVC animated:true];
    destroy(signupVC);
}

***注、destroy マクロは次のとおりです。

#define destroy($x)                                             \
if($x)                                                          \
{                                                               \
[$x release];                                               \
$x = nil;                                                   \
}

SignupViewController が作成されると、ViewDidLoad メソッドは次のようになります。

self.view = [[SignupView alloc] initWithFrame:self.view.frame];

    [[(SignupView *)self.view evtSignupButtonPressed] addHandler:AFFHandler(@selector(signupPressed))];
    [((SignupView *)self.view).profileImage addTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside];

[self.navigationController setNavigationBarHidden:false animated:true];

次に、次のような SignupView 内のビューの UI を作成します。

- (void)setupUI
{

    self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:IS_IPHONE5 ? @"genericBackground-568h.jpg" : @"genericBackground.jpg"]];

    _overlayView = [[UIView alloc] initWithFrame:self.frame];

    _scrollView = [[UIScrollView alloc] initWithFrame:self.frame];


    _profileImage = [[UIButton alloc] init];

    profileImageContainer = [[UIView alloc] initWithFrame:CGRectMake(18.5, 0, _profileImage.imageView.image.size.width + 10, _profileImage.imageView.image.size.height + 10)];


    selectProfilePictureText = [[UILabel alloc] initWithFrame:CGRectMake(profileImageContainer.affX, 0, 229, 17)];


    UIView *padding = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 17, 40)];

    _usernameField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
    _usernameField.delegate = self;

    _passwordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
    _passwordField.delegate = self;

    _repeatPasswordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];

    _repeatPasswordField.delegate = self;

    _emailField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
    _emailField.delegate = self;

    destroy(padding);

    buttonImage = [[UIImage imageNamed:@"largeButton.png"] copy];
    _submitButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height)];
    [_submitButton addTarget:self action:@selector(signupButtonPressed) forControlEvents:UIControlEventTouchUpInside];


    destroy(buttonImage);




    [self addSubview:_scrollView];
    [self addSubview:_overlayView];
    [_scrollView addSubview:profileImageContainer];
    [profileImageContainer addSubview:_profileImage];
    [_scrollView addSubview:selectProfilePictureText];

    [_scrollView addSubview:_usernameField];
    [_scrollView addSubview:_passwordField];
    [_scrollView addSubview:_repeatPasswordField];
    [_scrollView addSubview:_emailField];
    [_scrollView addSubview:_submitButton];


    destroy(profileImageContainer);
    destroy(selectProfilePictureText);

}

**注、backgroundColour の変更など、これらのオブジェクトのプロパティを変更するすべてのコードを省略しました。

SignupVC と SignupView の dealloc メソッドは次のとおりです。

SignupView:

- (void)dealloc
{

    self.usernameField.delegate = nil;
    self.passwordField.delegate = nil;
    self.repeatPasswordField.delegate = nil;
    self.emailField.delegate = nil;

    AFFRemoveAllEvents();

    destroyAndRemove(_usernameField);
    destroyAndRemove(_passwordField);
    destroyAndRemove(_repeatPasswordField);
    destroyAndRemove(_emailField);
    destroyAndRemove(_profileImage);
    destroyAndRemove(_submitButton);
    destroyAndRemove(_scrollView);
    destroyAndRemove(_overlayView);

    if(buttonImage)
        destroy(buttonImage);


    [super dealloc];
}

SignupVC (これは、NavigationBar の戻るボタンが押された後に呼び出されます)

    - (void)dealloc
    {
        [[(SignupView *)self.view evtSignupButtonPressed] removeHandlersForObserver:self];
        [((SignupView *)self.view).profileImage removeTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside];
        destroy(profileImage);
        destroyAndRemove(self.view);


        [super dealloc];
    }

DestroyAndRemove はこれを行います:

#define destroyAndRemove($x)                                    \
if($x)                                                          \
{                                                               \
[$x removeFromSuperview];                                   \
[$x release];                                               \
$x = nil;                                                   \
}
4

2 に答える 2

5

に切り替えますARC。真剣に、それを使用しない正当な理由はありません。また、メモリの問題を解決する可能性があります。

ARC1) Appleは、更新プログラムや新しいアプリで使用することを強く推奨しており、そのように述べています。

2) 新しいアプリの申請と更新の大部分は を使用ARCしており、ほとんどの場合、手動の参照カウントと同じくらい効率的であることが示されています (あなたのアプリもおそらく例外ではありません)。

3) ARCObjective-C 開発者としての生活を簡素化します。コードに 、 などをあちこちにrelease散らかすretain必要はもうありません。

4) 使いやすい変換ツールがあります。

後藤Edit> Refactor>Convert to Objective C ARC

ARC5) まだ ARC に切り替えていないサード パーティのライブラリを使用している場合でも (ほとんどの一般的なライブラリは既に切り替えています)、個々のファイルでの使用をオプトアウトできます。その方法については、この他のSO 投稿を参照してください。

に切り替えた後も問題が解決しない場合はARC(前述のように、に切り替えるとARCメモリの問題が解決する可能性があります)、再度アクセスしてください。

于 2013-09-29T00:33:24.313 に答える
4

どのような天体が降着していますか?

つまり、Allocations インストゥルメントを使用する場合は、「ライブ オブジェクトのみを追跡する」(または同等の名前の機能) をオンにします。次に、アプリを使用して、メモリ内に固執してはならないオブジェクトを調べます。参照イベント トラッカーもオンにします。

ほとんどの場合、これは保持サイクルです。たぶん、あなたのオブジェクトを強く参照しているタイマーですか?または、他の同様の関係。

メモリ内に残っているオブジェクトを特定したら、保持とリリースのインベントリをクリックして、バランスが取れていないものを確認する必要があります。

本当にARCを使用する必要があることに注意してください。

于 2013-09-29T01:10:11.033 に答える