ARCを導入するとメモリ管理がいい加減になりがちですが、
Blocksの循環参照など、メモリ管理の落とし穴は依然として多いです。
なので、テストを書く方法を考えました。

書き方

  • deallocされるか確認したいオブジェクトと同じ型の__weakな変数を宣言する。
  • @autoreleasepoolをつくり、その中で確認したいオブジェクトを作る。
  • つくったオブジェクトを__weakな変数に入れる。
  • @autoreleasepoolを閉じたあと、__weakな変数に対してSTAssertNilする。

確認したいオブジェクトの暗黙的な__strong@autoreleasepoolに収まるので、
@autoreleasepool外ではそのオブジェクトはdeallocされているはず、というわけです。

最近、NSURLConnectionをラップするNSOperationを改めて書いているので、それを例にします。
非同期のテストの書き方は@grassonion1 さんの方法に準じるものにしています。

- (void)testDeallocOnCancelBeforeStart
{
    __weak ISHTTPOperation *woperation;
    
    @autoreleasepool {
        NSURL *URL = [NSURL URLWithString:ISTestURL];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        ISHTTPOperation *operation = [[ISHTTPOperation alloc] initWithRequest:request handler:nil];
        woperation = operation;
        [operation cancel];
        [NSThread sleepForTimeInterval:.1];
    }
    
    STAssertNil(woperation, nil);
    self.isFinished = YES;
}

これで、cancelされたNSOperationがちゃんとdeallocされるか確認できます。
(もちろん、testDeallocOnCancelAfterStartも書いてあります。)

 

リポジトリはこちらです。
ISHTTPOperation