0

私は答えを得た後編集:
- 実際にはメモリリークはありません。 NSInvocationOperationに追加されたオブジェクトは保持され、期待どおりに解放されます。
NSIvocationOperationの終了後に引数が保持されますか?

なぜ私はNSInvocationOperationにオブジェクトを追加した後、それが保持され、また、その操作後にはそれがが再びを保持されて終了したこと、それですか?

メモリリークを防ぐにはどうすればよいですか?

下にサンプルコードがあります。 多くのコードがあなたを迷惑にしていたら謝りますが、私は何も見逃していないことを確かめたかったのです。 また、NSLogsの隣のコメントも出力されます。

マイ全体AppDelegate.m:

// 
// AppDelegate.m 
// BRISI 
// 
// Created by Aleksa Topic on 2/22/12. 
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 
// 

#import "AppDelegate.h" 

@implementation AppDelegate 

@synthesize window = _window; 

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

- (BOOL)application:(UIApplication *)application 
     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    NSObject *a = [[NSObject alloc] init]; 
    NSLog(@"a1: %d", a.retainCount); // a1: 1 

    NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] 
             initWithTarget:self 
              selector:@selector(s:) 
               object:a]; 
    NSLog(@"a2: %d", a.retainCount); // a2: 2 

    [a release]; 
    NSLog(@"a3: %d", a.retainCount); // a3: 1 

    [operationQueue addOperation:operation]; 
    [operation release]; 
    NSLog(@"a4: %d", a.retainCount); // a4: 1 

    NSLog(@"oper1: %@", operation); // oper1: <NSInvocationOperation: 0x6a3f7d0> 

    NSLog(@"a5: %d", a.retainCount); // a5: 1 
    NSLog(@"a5: %d", a.retainCount); // a5: 1 
    NSLog(@"a5: %d", a.retainCount); // a5: 1 
    NSLog(@"a5: %d", a.retainCount); // a5: 2 
    NSLog(@"a5: %d", a.retainCount); // a5: 2 
    NSLog(@"a5: %d", a.retainCount); // a5: 2 
    NSLog(@"a5: %d", a.retainCount); // a5: 2 
    NSLog(@"a5: %d", a.retainCount); // a5: 2 

    // And here I get: "Thread 1: Program received signal: "EXC_BADACCESS"." 
    NSLog(@"oper2: %@", operation); 

    self.window = [[[UIWindow alloc] 
        initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 
    // Override point for customization after application launch. 
    self.window.backgroundColor = [UIColor whiteColor]; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

- (void)s:(NSArray *)a 
{ 
    NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1 
    NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1 
    NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1 
} 

@end 

そして、ここでは、比較したい場合の出力です:私は事業のトリッキー保持/リリースセットで取り扱っておりますたび

GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all 
Attaching to process 7927. 
2012-03-06 16:19:20.712 BRISI[7927:207] a1: 1 
2012-03-06 16:19:20.715 BRISI[7927:207] a2: 2 
2012-03-06 16:19:20.715 BRISI[7927:207] a3: 1 
2012-03-06 16:19:20.716 BRISI[7927:207] a4: 1 
2012-03-06 16:19:20.717 BRISI[7927:207] oper1: <NSInvocationOperation: 0x6858da0> 
2012-03-06 16:19:20.717 BRISI[7927:1e03] a (s:): 1 
2012-03-06 16:19:20.717 BRISI[7927:207] a5: 1 
2012-03-06 16:19:20.718 BRISI[7927:1e03] a (s:): 1 
2012-03-06 16:19:20.718 BRISI[7927:207] a5: 1 
2012-03-06 16:19:20.718 BRISI[7927:1e03] a (s:): 1 
2012-03-06 16:19:20.719 BRISI[7927:207] a5: 1 
2012-03-06 16:19:20.719 BRISI[7927:207] a5: 2 
2012-03-06 16:19:20.720 BRISI[7927:207] a5: 2 
2012-03-06 16:19:20.720 BRISI[7927:207] a5: 2 
2012-03-06 16:19:20.721 BRISI[7927:207] a5: 2 
2012-03-06 16:19:20.721 BRISI[7927:207] a5: 2 
Current language: auto; currently objective-c 
(gdb) 
+2

'NSObject'をサブクラス化し、そこに' NSLog() 'を置く' dealloc'をオーバーライドし、 'NSInvocationOperation'のオブジェクトとして使用します。それは 'a'が実際にリリースされることを安心するのに役立ちます。保持カウントについて心配するのを止めなさい - 彼らは狂ったようにスパイクするかもしれないので、あなたに何も言わないでしょう。 – Costique

+0

@Costiqueしかし、その 'dealloc'は決して呼び出されません(' dealloc'が呼び出されると、オブジェクトはなくなります)。 'a.retainCount'はアプリをクラッシュさせていないので、例から見ることができます。 – Aleksa

+0

投稿したコードにリークがないので、とにかく呼び出されます。オペレーションの割り当てが解除されるまでに、呼び出しオブジェクトが自動解放プールに追加された可能性があり、解放が遅れます。 'NSInvocationOperation'はオブジェクトを保持する' NSInvocation'を作成することに注意してください。これは 'retainCount == 2'をどこから取得しているのかを説明します。 – Costique

答えて

0

私が作ります私は適切なメソッドをオーバーライドしてください:

@interface RetainCountChecker : NSObject 

@end 

@implementation RetainCountChecker 

-(oneway void)release{ 
    [super release]; 
    NSLog(@"release - retainCount = %d", [self retainCount]); 
} 

-(id)retain{ 
    id result = [super retain]; 

    NSLog(@"retain - retainCount = %d", [self retainCount]); 
    return result; 
} 

-(void)dealloc{ 
    [super dealloc]; 
} 

@end 

リテールにブレークポイントを置く、release 、deallocメソッドを使うと、それぞれのメソッドが呼び出された日時や方法を見ることができます。 あなたの場合、NSInvocationOperationは内部NSInvocationオブジェクトを自動リリースしています。 didFinishLaunchingWithOptions:メソッドが返す

@autorelease{ 

} 

ブロックに問題のコードをラップする「」-application前をDEALLOCます。

+0

実際に解放されます。混乱は、 'NSInvocationOperation'が解放されていて、私のオブジェクトがすぐに解放されないというものでした。 – Aleksa

関連する問題