Objective-C: typedef avais un bloc, dans une déclaration de méthode. Comment puis-je mettre en œuvre?

Juste essayer d'obtenir une poignée sur les blocs. Je reçois le concept. Ils sont comme des pointeurs de fonction, mais ils sont en fait des objets; vous pouvez déclarer une variable d'un bloc et lui attribuer une valeur de blocage; l'appeler comme une fonction; ils se "figé dans le temps," faute d'un terme, lorsqu'elles sont exécutées, etc. J'ai créé quelques blocs et de les exécuter avec succès, dans différents formats, mais quand il s'agit de les utiliser dans une méthode, soit avec un typedef ou sans--je vais avoir beaucoup de mal. Par exemple, voici une interface d'un objet que j'ai créé, juste pour obtenir une poignée sur la syntaxe. Je n'ai presque aucune idée de comment le mettre en œuvre.

//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

Voici ce que j'ai pour une mise en œuvre à ce jour:

#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

Je sais que je ne suis pas aborder la variable d'instance encore. Encore une fois, c'est un brouillon, juste essayer d'obtenir une poignée sur la façon dont les blocs de travail. Suis-je à même de déclarer cette méthode à droite? Je suis en train de lire Big Nerd Ranch de l'Objective-C Programmation, Mike Clark article sur les blocs de Pragmatique Studio, et plusieurs threads. Ne pouvez pas trouver quelque chose de pertinent. Merci.

EDIT: XCode 4.3.2, si il le faut.

PLUS EDIT: Ok. À l'aide de BJ (légèrement modifié), par exemple, je pense que je suis venu avec un vraiment compliqué de multiplication de 5 par 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;
}

Principal:

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

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

    }
    return 0;
...

Et la sortie est:

15

Maintenant, c'est un coup de pied 15, parce que le bloc que j'ai définie comme un argument est exécuté qu'une seule fois, non? Il multiplie les "le nombre," qui est de 5 dans ce cas, par 3 et gèle la réponse, non? Je suis sûr que je viens de créer un complètement inutile méthode, et je n'ai pas encore compris comment utiliser les avantages et les caractéristiques d'un bloc. Suis-je la corriger?

/********************* Mise à JOUR *********************/

Mise à JOUR: je comprends ce que vous dites, le CRD. Juste une correction bien que, pour les nouveaux programmeurs qui peut être la lecture de cette, de se de sortie et d'aller, "Que?" Votre pour la boucle doit être soit:

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

...ou...

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

...pour obtenir la réponse 243.

Et, oui, c'est exactement ce que j'ai d'abord essayé de faire avec ce code. Au moins, c'est ce que je pensais était censé se produire. S'avère l'intention de l'auteur n'était pas le triple d'un nombre, stocker cette valeur, le triple de la valeur stockée, magasin, etc..., mais plutôt juste pour imprimer x * 3 pour les nombres 1-5 (3, 6, 9, 12, 15).

Ici est le produit fini. Je viens de typedef avais un bloc qui prend un entier et retourne un int, appelé à Tripler. J'ai aussi changé le nom de l'argument de la "someBlock" à "triple" pour indiquer plus clairement l'utilisation prévue du bloc. Je pense que ce sont les seules modifications au code.

/********************  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;
}

Comme vous pouvez l'imaginer, le résultat est:

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

Je faisais beaucoup plus compliqué que nécessaire. Désolé pour l'expliquer si mal dans l'OP. Merci pour votre aide! /thread? 🙂

Aller à travers ce Bloc Explication... highoncoding.com/Articles/...

OriginalL'auteur baptzmoffire | 2012-05-03