0

ブロックの扱い方がわかりません。たとえば、viewDidLoad で関数「useDocument」を呼び出して Core Data をセットアップしました。Core Data を使用する準備が整い次第、何らかのクエリを処理するために別の関数が呼び出されることを願っています。ASIHTTPRequestと同様 に、クライアントが応答を受信すると、関数が呼び出されて応答が処理されます。

関数をトリガーすることは、ブロックを操作する正しい方法ではないと思います。しかし、正しい方法は何ですか?

- (void)useDocument
{
    if (!self.database) {
        self.database = [DataModelDocument sharedDocument];
    }

    if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
        // does not exist on disk, so create it
        [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
                if (!success) {
                    NSLog(@"database doesn't exist on disk, we fail to create it");
                }
        }];
    } else if (self.database.documentState == UIDocumentStateClosed) {
        // exists on disk, but we need to open it
        [self.database openWithCompletionHandler:^(BOOL success) {
            if (!success) {
                NSLog(@"database exists on disk, but we fail to open it");
            }
        }];
    } else if (self.database.documentState == UIDocumentStateNormal) {
        // already open and ready to use
    }
}
4

2 に答える 2

1

関数の正しい使い方がないように、ブロックの正しい使い方もありません。

ブロックは関数です。機能以上のものですが、大きな違いはありません。だから今は違いを忘れましょう。機能。

関数を使用して、次のように記述します

void callback (BOOL success) {
    if (success) {
        // do something useful
    }
}

[database openWithCallback: &callback];

ここにある種の小さなエンディアンがあります。Hは。

ブロックを使用すると、コールバックをインラインで記述できます。

[self.database openWithCompletionHandler: ^(BOOL success) {
    if (!success) {
        // oops, handle that
    }
}];

その特定のケースでは、ブロックは関数が解決できなかった問題を解決しません。彼らはより均等に費用がかかります。

メリットは、たくさん使うことで発揮されます。操作を完全に非同期に記述すると、コードを合理化された方法で記述できます。

疑似コード:

dispatch block: ^(){
    some heavy computation here
    dispatch block: ^(){
        computation done, update the UI or something
    }
}

非常に単純な例。もちろん、これを関数で書くことは完全に可能です。しかし、読むほどではありません。

大量のブロックをディスパッチしていると想像してください。ブロックのグループを作成し、グループが完全に実行されたときにブロックを実行できます。とても書きやすく、とても読みやすい。これは、いたるところで関数ポインタを扱う悪夢になり始めています。

では、何がブロックを関数以上のものにしているのでしょうか?

ブロックは関数です。コンテキスト付き。ブロックは同じスコープ内の変数にアクセスできます。上記の単純な例では、作業ブロックは呼び出しスコープにアクセスでき、完了ブロックは呼び出しスコープと作業ブロック スコープにアクセスできます。もちろん、これは関数と構造体で行うことができます。コードが多いと、読みにくくなります。ブロックはそれをよりエレガントに解決します。

Grand Central Dispatchについて読むことをお勧めします。これは明らかに、ブロックが真の可能性と表現力を発揮する場所です。

于 2012-06-19T08:55:07.133 に答える
0

ブロックは一種の「ステートフル スレッド」と考えることができます。私は「ある程度」を強調します。これは、コードと変数が素敵なコードの小さな「ブロック」にカプセル化されたものです。

__block を使用して、変数をブロックの外側からスコープに取り込むことができます。ブロックは、周囲の残りのコードが完了すると実行されます。

この場合、完了ブロックを使用しています。メソッドを呼び出すのに適切なタイミングが、その周りのすべてのコードが完了した後である限り、必要に応じてそこにあるメソッドを呼び出すことができます。

于 2012-06-19T03:41:25.220 に答える