2

たとえば、authenticateHandler

@property(nonatomic, copy) void(^authenticateHandler)(UIViewController *viewController, NSError *error)

小さな帽子^(UIViewController *viewController, NSError *error)は、呼び出しに無名関数ブロックが必要であることを示しています。

[lp setAuthenticateHandler:(^( UIViewController* vc, NSError *nsError )
  {
    if( !nsError )
    {
      puts( "GC auth success" ) ;
    }
  })];

しかし、呼び出しで使用している関数を名前付き関数にしたいとsetAuthenticateHandlerます。の使用を見た他の場所ですが@selector(functionName)、ここでは機能していないようです。

4

2 に答える 2

1

ブロック、セレクター、および関数ポインター (後の 2 つのうちどちらを名前付き関数として参照しているかは不明) はすべて互換性のない型であるため、別の型の引数が必要な場所に渡すことはできません。幸いなことに、ブロックベースの API で関数ポインターまたはセレクターを使用する必要がある場合は、非常に簡単に使用できます。ブロックは、作成時にスコープ内にある関数ポインターとセレクターをキャプチャし、ブロック内で使用できます (他の変数と同様に)。たとえば、次のビュー コントローラーは、セレクターまたは関数ポインターを引数として受け入れる GCD (ブロック ベースの API) へのラッパーを提供します。

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

ViewController.m:

#import "ViewController.h"

void callback() { NSLog(@"call back function"); }

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self doSomethingWithCompletionSelector:@selector(callback)];
//    [self doSomethingWithCompletionFunction:callback];

}

- (void)callback
{
    NSLog(@"call back selector");
}

- (void)doSomethingWithCompletionSelector:(SEL)selector
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
        NSLog(@"Doing something");
        // Causes a warning in ARC
        [self performSelector:selector];
    });
}

- (void)doSomethingWithCompletionFunction:(void (*)())function
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Doing something");
        function();
    });
}

@end

もちろん、任意のメソッドまたは関数を明示的に呼び出すことができ、レシーバーと引数はすべてブロックによってキャプチャされます。

于 2013-03-29T06:32:40.470 に答える
0

セレクターとブロックはまったく別の概念です。

A@selector(functionName)はタイプSEL

Ablockは C レベルの構文ランタイム機能であり、Objective-C では実際にはオブジェクトです。

セレクターの詳細については、こちらを確認してください。

ブロックの詳細については、こちらを確認してください。

于 2013-03-29T05:31:31.150 に答える