You are here: Home / TinBlog / ARCと__bridgeとバグ退治

ARCと__bridgeとバグ退治

Posted by h2 at Mar 16, 2012 04:50 PM |
Filed under: ,
ARC。便利ではあるのだが、ややもすると、とんでもなく原因を追及しにくいバグが出てしまうことに。

とにかく、デバッガがまともにエラーを報告してくれないせいで、原因追及に数日間もかかってしまったのですよ。

・・・いやその。バグを出してしまったのは、自分なんだけどね。

 

問題となったのは、sharedを用いた某ネットワーククラスの、まさにshared用のメソッド。

+ (MyNetManager *)sharedNetManager
{
	static __strong MyNetManager	*__sharedNetManager = nil;
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		__sharedNetManager = [[MyNetManager alloc] init];
	});
	
	return __sharedNetManager;
}

このshaedメソッド呼び出しの、数回目で強制終了を引き起こしていたのですよ。

 

この場所を特定するだけでも、ほぼ一日近く時間がかかってしまった。

というのも、あろうことかデバッガーが、試行するたびに異なる場所でのエラーを報告してきたからだ。

それも、この近辺というのならともかく、時によって、「UIButtonのターゲットが見つかりません」だの、「NSObjectに変なメッセージ送ってます」だの、もう、あり得ないエラーが目白押し。

 

そういったゴミのようなエラー情報の山から、数十回の試行錯誤を経て、ようやくたどり着いたのが、ここ。

だが、プログラムコード自体には、どう見てもエラーらしきコードは無い。

 

そこで、さらに原因を追求したところ、どうやら__sharedNetManagerのインスタンスが、どこかのタイミングで解放されてしまっているのが原因らしい、ということが分かった。

 

・・・が。

今回は、ARCを使用している。

 

・・・つまり。

自分ではreleaseしていないわけで。

 

とどのつまり、「ARCがどっかで解放してしまっている原因を突き止めろ」というミッションなわけで。

・・・・・・チョーン (;o;)

 

ええ、もう涙目ですよ。

で、延々と調べていったところ、ようやく原因を見つけました。

どこかというと、なんと、Reachabilityを調べる関数のコールバックのなか。

static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
{
	if ([(__bridge NSObject *)info isKindOfClass:[MyNetManager class]]) {
		MyNetManager	*nmgr = (__bridge_transfer MyNetManager *)info;
		[nmgr updateReachabilityStatWithFlags:flags];
	}
}

・・・そう、このなかでMyNetManagerインスタンスの確保にあたり、うっかり__bridge_transferを使用していたせい。

 

てか、なぜ__bridge_transferになっているかな、こいつ。ばたばた打ち込んでいたせいで、オートコレクトを間違えたんだろうか。

ともあれ、ここの__bridge_transferを__bridgeに変更することで、ようやく原因不明のバグの嵐から解放されたのでした。

 

・・・・・・・・・・・。

あー。もー。ARCでメモリバグが出ると、ここまでマンドクサイとは思わなかった。

__bridgeを使う際には、十分注意しましょう。

Filed under: ,
« November 2019 »
November
SuMoTuWeThFrSa
12
3456789
10111213141516
17181920212223
24252627282930