頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


返り値の型が一致してないだと?

なんで???ってエラーにぶつかって無駄な時間を使っちゃったのでメモしておくよ。

こういう形のブロックを返すクラスメソッドがあったんだ。
typedef id (^ HogeBlock)(int number);//Blockの定義


+(HogeBlock)getHogeBlock
{
    return (id)^(int number) {

        //引数に応じた処理

        NSMutableData *data = …
        return data;
    };
}
ところがどういうわけか最後のreturn部分を指してエラーがあるとXcodeが言うんだ。

エラーメッセージ return type must match
Return type 'NSMutableData *' must match previous return type 'void *' when block literal has unspecified explicit return type

なんでこれでエラー出るんだよ?って散々悩んでいたんだけどさ、ようやくわかったのが
//引数に応じた処理
って部分にエラーチェック用で
if (something) return nil;
みたいな部分があったんだ。これが原因。
そうわかるとエラーメッセージが何を言ってるのかわかったよ。
ブロック構文において明確な返り値を記述しない場合、この返り値の型'NSMutableData *'は前述の型'void *'と一致しないとだめだよ!
ってことか。previousがブロックの宣言文の形式のことかと思ってたからXcodeは何を言ってるんだよ?ってはまってたんだな。

idだからなにを返してもいいってわけではなくて、返り値の型が全部同じかチェックしてて、一致しないと最初の方には何も記述なしで、二つ目以降にエラーって出るんだ。 どうせならその最初の部分もはっきりと示してくれればいいのに!って言っても仕方ないか。これからは気をつけようっと。


if (something) return (NSMutableData *)nil;
↑エラー自体はキャストしてやれば回避できるけど、、、ダサっ!
そもそも返り値を持つ関数などで途中でぷいっと処理を中断して戻る、なんて記述しちゃだめなのかな。
後からチェックする時に途中にさりげなくreturn文なんかがあると理解しにくくなるとか。
NSMutableData *data = nil;
if (something) {
    //trueの場合の処理
} 
return data;
↑こういう形にしてreturnは一つだけってコーディングルールにしておく方が理解しやすいかも。

みんなどうしてるんだろうな、と思って調べると、、、ずばりこんのがあったよ!

関数の途中でreturnはしてはいけない? - Yahoo!知恵袋

なるほど、returnは一つだけってルールにすると最後まで読まないとだめ、か、、、確かにそうだね。
下の方の回答に処理が終わってることを//------------------> のようなコメントで明記するってのがあるけど、こういうのがいいかも。


ちなみに、ブロック構文じゃなくて普通のメソッドの返り値がid型だと
-(id)testReturnValue
{
    if (1) return nil;
    
    return @"hoge";
}
なんて記述してもエラーは出ない。そうかあ、ブロック構文だとちょっと違うんだねえ。

<< id型のオブジェクトのプロパティへアクセスできない?   TopPage  iPhoneのタブバーをフラットデザインっぽく変えてみる >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
http://ringsbell.blog117.fc2.com/tb.php/790-bbd007ef




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad