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 Programming、Mike Clark 关于来自 Pragmatic Studio 的块的文章以及几个 SO 线程。找不到任何相关的东西。谢谢。

编辑:XCode 4.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

现在,它回退了 15,因为我定义为参数的块只运行一次,对吗?它将“数字”(在这种情况下为 5)乘以 3 并冻结该答案,对吗?我确定我只是创建了一个完全没用的方法,而且我还不明白如何利用块的好处/功能。我对么?

/ * ** * ** * ** * ** * ** * ** * ** 更新 ** * ** * ** * ** * ** * ** * ** * /

更新:我明白你在说什么,CRD。不过,对于任何可能正在阅读本文的新程序员来说,这只是一个更正,得到不同的输出并会问,“Que?” 您的 for 循环应该是:

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

...或者...

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

...得到答案 243。

而且,是的,这正是我最初试图用这段代码做的事情。至少那是我认为应该发生的事情。原来作者的意图不是把一个数字加三倍,存储那个值,把存储的值加三倍,存储那个……等等,而只是为数字 1-5 打印 x * 3 (3, 6, 9, 12、15)。

这是成品。我只是键入了一个块,它接受一个 int 并返回一个 int,称为 Tripler。我还将参数的名称从“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次的结果;例如,如果您两次应用三倍函数,您将得到原始值乘以九。

以防万一它有帮助,这是执行此操作的代码:

@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
    }
}

在“进一步编辑”后更新

不,您作为参数传入的块运行五次,每次都通过 for 循环。

  • 第一次,它调用1作为参数的块,然后返回3。它将其存储在 中blockReturnValue,然后继续循环的下一次迭代。
  • 第二次,它调用2作为参数的块,然后返回6。它将其存储在其中blockReturnValue完全覆盖了我们在前一次传递中存储的值
  • 第三次,它使用3作为参数的块,并返回9。同样,它会覆盖blockReturnValue.
  • 第四次,我们存储12blockReturnValue.
  • 第五次,我们存储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 回答