9

ブロックのハンドルを取得しようとしています。コンセプトがわかります。これらは関数ポインタに似ていますが、実際にはオブジェクトです。ブロック変数を宣言して、それにブロック値を割り当てることができます。関数のように呼び出します。用語がない、実行されるなどの理由で、「時間内に凍結」されます。いくつかのブロックを作成し、いくつかの異なる形式で正常に実行しましたが、メソッドでの使用に関しては- -typedefの有無にかかわらず--私は多くの問題を抱えています。たとえば、構文を理解するために作成したオブジェクトインターフェイスを次に示します。どうやって実装すればいいのかほとんどわかりません。

// AnObject.h

#import <Foundation/Foundation.h>

// The idea with the block and the method below is for the block to take
// an int, multiply it by 3, and return a "tripled" int.  The method
// will then repeat: this process however many times the user wants via
// the howManyTimes parameter and return that value in the form of an int.

typedef int (^triple)(int);

@interface AnObject : NSObject
{
    int num;
}

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock;

@end

これまでのところ、実装のために私が持っているものは次のとおりです。

#import "AnObject.h"

@implementation AnObject

@synthesize num;

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock {
    for (int i = 0; i <= howManyTimes; i++) {
        // What the heck am I supposed to put here?  I'm baffled by the
        // syntax over and over again.
    }
}

@end

私はまだインスタンス変数に対処していないことを知っています。繰り返しになりますが、これは大まかなドラフトであり、ブロックがどのように機能するかを把握しようとしているだけです。私もこの方法を正しく宣言していますか?Big Nerd RanchのObjective-Cプログラミング、PragmaticStudioのブロックに関するMikeClarkの記事、およびいくつかのSOスレッドを読んでいます。関連するものが見つかりません。ありがとう。

編集:重要な場合は、XCode4.3.2。

さらに編集:わかりました。BJの(少し変更された)例を使用して、5に3を掛ける非常に複雑な方法を思いついたと思います。:)

// BJ's implementation:

-(int)repeat:(int)howManyTimes withBlock:(Triple)someBlock {

    int blockReturnValue;

    for (int i = 0; i <= howManyTimes; i++) {
        blockReturnValue = someBlock(i);
    }
    return blockReturnValue;
}

主要:

...
    @autoreleasepool
    {
        AnObject *obj = [[AnObject alloc] init];

        NSLog(@"%d", [obj repeat: 5 withBlock: ^ (int number) {
            return number * 3;
        }]);

    }
    return 0;
...

そして、出力は次のとおりです。

15

引数として定義したブロックは1回だけ実行されるので、今は15をキックバックしていますよね?「数」(この場合は5)に3を掛けて、その答えをフリーズしますよね?完全に役に立たないメソッドを作成したばかりで、ブロックの利点/機能をどのように利用するかはまだわかりません。私は正しいですか?

/ * ** * ** * ** * ** * ** * ** * ** アップデート ** * ** * ** * ** * ** * ** * ** * /

更新:CRD、あなたの言っていることがわかります。ただし、これを読んでいて、別の出力を取得して「Que?」forループは次のいずれかになります。

for (int i = 0; i < howManyTimes; i++)
            value = someBlock(value);

...また...

(i = 1; i <= howManyTimes; i++)

...答えを得るには243。

そして、はい、これはまさに私が最初にこのコードでやろうとしていたことです。少なくとも、それが起こっているはずだと私は思っていました。著者の意図は、数値を3倍にし、その値を格納し、格納された値を3倍にし、それを格納することなどではなく、数値1〜5(3、6、9、 12、15)。

これが完成品です。トリプラーと呼ばれる、intを取り、intを返すブロックをtypedefしました。また、引数の名前を「someBlock」から「triple」に変更して、ブロックの使用目的をより明確に示しました。コードへの変更はこれだけだと思います。

/********************  interface  ********************/


#import <Foundation/Foundation.h>

typedef int (^Tripler)(int);

@interface AnObject : NSObject

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple;

@end

/********************  implementation  ********************/


#import "AnObject.h"

@implementation AnObject

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple {
    for (int i = 1; i <= number; i++) {
        NSLog(@"%d", triple(i));
    }
}

@end

/********************  main.m  ********************/


#import "AnObject.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        AnObject *obj = [[AnObject alloc] init];

        [obj iterateFromOneTo:5 withBlock:^(int number) {
            return number * 3;
        }];
    }
    return 0;
}

ご想像のとおり、結果の出力は次のとおりです。

2012-05-05 17:10:13.418 Untitled 2[71735:707] 3
2012-05-05 17:10:13.445 Untitled 2[71735:707] 6
2012-05-05 17:10:13.446 Untitled 2[71735:707] 9
2012-05-05 17:10:13.446 Untitled 2[71735:707] 12
2012-05-05 17:10:13.447 Untitled 2[71735:707] 15

必要以上に複雑にしていました。OPでの説明が不十分でごめんなさい。ご協力いただきありがとうございます!/スレッド?:)

4

3 に答える 3

8

あなたの質問を読んだことから、私はあなたの意図があなたのブロックをn回適用した結果を生み出すことであると理解したか、あるいは誤解したかもしれません。たとえば、3倍関数を2回適用すると、元の値に9を掛けた値になります。

それが役立つ場合に備えて、これを行うためのコードは次のとおりです。

@interface AnObject

typedef int (^monadic)(int); // an function which takes an int and return an int

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock;

@end

@implementation AnObject

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock
{
   for (int i = 0; i < howManyTimes; i++)
      value = someBlock(value);

   return value;
}

@end

これを次のように呼び出します。

AnObject *myObject = [AnObject new];

int z = [myObject repeat:5  
                     for:1 
               withBlock: ^(int number)
                          {
                             return number * 3;
                          }
        ];

z値はになります243

于 2012-05-04T02:27:46.390 に答える
7

通常のC関数のようにブロックを呼び出すだけです。

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock {
    for (int i = 0; i <= howManyTimes; i++) {
        int blockReturnValue = someBlock(i);
        // do something with blockReturnValue
    }
}

「さらに編集」した後に更新する

いいえ、引数として渡したブロックは5回実行され、それぞれがforループを通過します。

  • 初めて1、引数としてブロックを呼び出し、戻り3ます。それをに格納しblockReturnValue、ループの次の反復に進みます。
  • 22回目は、引数としてブロックを呼び出し、戻り6ます。それをに保存しblockReturnValue前のパスで保存した値を完全に上書きします
  • 33回目は、引数としてでブロックを呼び出し、戻り9ます。繰り返しますが、。の値を上書きしますblockReturnValue
  • 4回目はに保存12blockReturnValueます。
  • 5回目はに保存15blockReturnValueます。

次に、forループを終了し、15を返します。そうです、3を掛ける無意味なメソッドを作成したのは正しいです。しかし、無駄な計算を大量に実行する方法で実行しています。

于 2012-05-03T21:43:06.303 に答える
1
@import Foundation;

typedef int(^MyBlockType)(int);

@implementation NSObject(extra)
+ (int)invokeBlock:(MyBlockType)block withArgument:(int)arg
{
    return block(arg);
}
@end;

int main() {
    @autoreleasepool {
        NSLog(@"executeBlock(3) returns %d",
              [NSObject invokeBlock:^(int param) { return param * param; } withArgument:3]);
    } return 0;
}
于 2015-06-06T22:10:52.150 に答える