2010-09-09 13 views
9

¿Cómo puedo crear mis propios métodos que toman un bloque como argumento y que puedo llamar más tarde?¿Cómo puedo crear mis propios métodos que toman un bloque como argumento y al que puedo llamar más tarde?

He intentado seguir cosas.

#import <UIKit/UIKit.h> 
typedef void (^viewCreator)(void); 

@interface blocks2ViewController : UIViewController 
{ 
} 
-(void)createButtonUsingBlocks:(viewCreator *)block; 

@end 


- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self createButtonUsingBlocks:^(NSString * name) { 
     UIButton *dummyButton = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 200, 100)]; 
     dummyButton.backgroundColor = [UIColor greenColor]; 
     [self.view addSubview:dummyButton]; 
    }]; 
} 

-(void)createButtonUsingBlocks:(viewCreator *)block 
{ 
    // Do something 
    NSLog(@"inside creator"); 
} 

También he intentado pasar la variable del bloque a mi método personalizado, pero sin éxito. ¿Por qué es así y cuál es la forma correcta de hacerlo?


actualización

Este es el archivo is.h:

#import <UIKit/UIKit.h> 

typedef void (^viewCreator)(void); 

@interface blocks2ViewController : UIViewController 
{ 

} 
- (void)createButtonUsingBlocks:(viewCreator)block; 
@end 

Y esta es la imagen .m:

#import "blocks2ViewController.h" 

@implementation blocks2ViewController 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
     [self createButtonUsingBlocks:^(NSString * name) { 
     UIButton *dummyButton = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 200, 100)]; 
     dummyButton.backgroundColor = [UIColor greenColor]; 
     [self.view addSubview:dummyButton]; 
     [dummyButton release]; 
    }]; 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload { 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

// ... 

-(void)createButtonUsingBlocks:(viewCreator)block 
{ 
// viewCreator; 
    NSLog(@"inside creator"); 
} 
@end 
+0

favor * añadir actualizaciones * en lugar de cambiar la pregunta original y comprobar el formato en la vista previa * antes * de su publicación. –

+0

La actualización todavía tiene el problema con typedef - change 'typedef void (^ viewCreator) (void);' a 'typedef void (^ viewCreator) (NSString *);' –

Respuesta

12

Primera la typedef es apagado si desea permitir que los bloques tienen un parámetro de cadena:

typedef void (^viewCreator)(NSString*); 

En segundo lugar el tipo de bloques es:

ReturnType (^)(ParameterTypes...) 

y no

ReturnType (^*)(ParameterTypes...) 

Así, hay no es necesario agregar punteros al tipo viewCreator:

- (void)createButtonUsingBlocks:(viewCreator)block; 

Tercer realidad se tiene que llamar al bloque si usted no está haciendo que aún:

-(void)createButtonUsingBlocks:(viewCreator *)block { 
    block(@"button name"); 
    // ... 

Cuarta y por último, la UIButton es sobre-retuvieron - que debe release o autorelease que:

UIButton *dummyButton = [[UIButton alloc] initWithFrame:...]; 
// ...  
[self.view addSubview:dummyButton]; 
[dummyButton release]; 

Lanzar todo eso junto:

#import <UIKit/UIKit.h> 
typedef void (^viewCreator)(NSString*); 

@interface blocks2ViewController : UIViewController {} 
-(void)createButtonUsingBlocks:(viewCreator)block;  
@end 

@implementation blocks2ViewController 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self createButtonUsingBlocks:^(NSString *name) { 
     UIButton *dummyButton = 
      [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 200, 100)]; 
     dummyButton.backgroundColor = [UIColor greenColor]; 
     [self.view addSubview:dummyButton]; 
     [dummyButton release]; 
    }]; 
} 

-(void)createButtonUsingBlocks:(viewCreator)block { 
    block(@"my button name"); 
} 
@end 
+0

No, todavía no funciona para mí ... –

+0

@Ajay: ver la edición, ¿en verdad llamas al bloque en alguna parte? –

+2

Awesome answer. Una nota adicional; si su objetivo es almacenar el bloque y llamarlo más tarde, debe 'copiar' el bloque.Los bloques comienzan en la pila y sucederán cosas muy malas si se llama a un bloque que no se copió después de que se destruyó el marco de pila declarante. – bbum

6

También puede hacerlo de esta manera sin pre-definir el método:

@interface blocks2ViewController : UIViewController 
-(void)createButtonUsingBlocks:(void (^)(NSString *name))block; 
@end 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self createButtonUsingBlocks:^(NSString * name) { 
     UIButton *dummyButton = [[UIButton alloc]initWithFrame:CGRectMake(50, 50, 200, 100)]; 
     dummyButton.backgroundColor = [UIColor greenColor]; 
     [self.view addSubview:dummyButton]; 
    }]; 
} 

-(void)createButtonUsingBlocks:(void (^)(NSString *name))block 
{ 
    block(@"My Name Here"); 
} 
Cuestiones relacionadas