11

iOSでブロックを使用する方法を理解しようとしています。私はAppleのドキュメントを読みましたが、いつものように、それらは曖昧で不完全であり、いくつかの重要な情報は言及されていません。私も成功せずにググった。これは私がそれを理解するための練習としてやろうとしていることです。

文字列を読み取り、その文字列を前回の読み取りと比較するためのブロックを作成しました。文字列が同じでない場合はYESを返し、同じ場合はNOを返します。

これは私がした方法です:

私はこれを.hで宣言しました

BOOL (^differentStrings)(void);

これを.mで、viewControllerのviewDidLoad内で宣言しました

__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){

    currentString = [self getString];
    NSLog(@"%@", currentString); // not printing anything on console

    if (![currentString isEqualToString:previousString]) {
        previousString = currentString;
        return YES;
    } else {
        return NO;
    }
};

これが私が使用する方法です:私はこれを行うスレッドを持っています:

if (differentStrings)
  NSLog (@"strings are different);

これらは私が持っている問題です:

  1. ブロックは常にYESを返します(文字列は異なります)
  2. これをvideDidLoad内で宣言するのは気が進まない。これをメソッドとしてグローバルに使用できるように、どのように宣言する必要がありますか?メソッドの場合と同じようにこれを配置する必要がありますか?
  3. ブロック内でメソッド「getString」を呼び出しています。大丈夫ですか?
  4. .mでブロック変数を宣言するのは奇妙だと思います。ご覧のとおり、ブロック変数を.hで宣言してから、.mで使用する必要があります。私はそれをやろうとしましたが、エラーが発生しました。
  5. ブロックの最初の行にデバッグポイントを設定しましたが、そこで停止していません。
  6. ブロック内のNSlog行は何も出力しません。ブロックが呼び出されていませんか?

皆さん、これを手伝ってくれませんか?

4

2 に答える 2

15

ブロックがどのように機能するかを誤解しています。(わかりました、それはちょっと明白です。)previousStringNSStringを指す変数であるのと同じように、ブロックdifferentStringsを指す変数です。ブロックを実行した結果ではなく、ブロック自体の結果です。つまり、これを行った後:

__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){

    currentString = [self getString];
    NSLog(@"%@", currentString); // not printing anything on console

    if (![currentString isEqualToString:previousString]) {
        previousString = currentString;
        return YES;
    } else {
        return NO;
    }
};

differentStringsブロックを指す変数です。したがって、これを行うと、次のようになります。

if (differentStrings)

differentStrings0またはNULL以外のものが含まれているかどうかをチェックしているだけです。ブロックが含まれているため、空ではないため、trueと評価されます。

注意:differentStringsはブロック変数であり、BOOL変数ではありません。これにはブロック(必要に応じて関数)が含まれており、呼び出されるとブール値が返されます。したがって、実際にブロックを実行するには、ブロックを呼び出す必要があります。このような:

differentStrings();

または、あなたの場合:

if (differentStrings()) {
    NSLog (@"strings are different");
}

編集:コメントで指摘されているように、はインスタンス変数であるため、インスタンス変数に割り当てられた他のオブジェクトを呼び出すのと同じように、それを行うdifferentStrings必要があります。(技術的な理由から、ここでは説明しません。常に代わりにブロックを使用する必要があります。)同様に、後で、おそらくメソッドで呼び出す必要があります。copyretaincopyretainreleasedealloc

于 2011-01-06T17:21:16.310 に答える
4

あなたが実際にブロックを実行しているとは思わない。あなたのコードは

if (differentStrings())
{
    NSLog (@"strings are different);
}

ブロックを関数のように扱います。ブロックが定義されているかどうかを確認しているだけで、実行していないと思います。

また、ブロックの外部でNSStringにアクセスする必要がない場合は、__block修飾子を削除して、currentString宣言をブロックの内部に移動できます。

ブロックに関する別のリソースが必要な場合は、iTunesUの高度なiOS開発コースの秋のセッションで取り上げます。ブロック構文については、「Cocoaの理解」セッションと、マルチスレッドセッション内のGrandCentralDispatchでの使用について説明します。コースノートには、さまざまな方法でブロックを使用するいくつかのサンプルアプリケーションへのリンクもあります。

また、 WWDC2010のビデオセッション206-iPhoneでのブロックとGrandCentralDispatchの紹介および211-GrandCentralDispatchによるiPhoneアプリ開発の簡素化をご覧になることを強くお勧めすることはできません。

于 2011-01-06T17:20:35.567 に答える