3

を受け取り、その文字列に対して をNSString返すブロックを定義しました。NSURL

id (^)(id obj)

私はtypedefそれを名前付きのブロックにしていました:

typedef id (^URLTransformer)(id);

また、次の方法は機能しません。

+ (URLTransformer)transformerToUrlWithString:(NSString *)urlStr
{
    return Block_copy(^(id obj){
        if ([obj isKindOfClass:NSString.class])
        {
            NSString *urlStr = obj;
            return [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        }
        return nil; // **THIS LINE FAILS**
    });
}

エラー:

ブロック リテラルに明示的な戻り値の型が指定されていない場合、戻り値の型 'void *' は前の戻り値の型 'id' と一致する必要があります

私の質問は次のとおりです。1.メソッドを正しく実装する方法2.typedef URLTransformerなしでメソッドを実装する方法は?

ありがとう

4

2 に答える 2

3

1.

ブロックにキャストするidか、タイプを追加することができます。以前に同様の質問をし、回答から引用しました

そのエラーを取り除く正しい方法は、ブロック リテラルの戻り値の型を提供することです。

id (^block)(void) = ^id{
    return nil; 
};

あなたの場合

+ (URLTransformer)transformerToUrlWithString:(NSString *)urlStr
{
    return Block_copy(^id(id obj){ // id here
        if ([obj isKindOfClass:NSString.class])
        {
            NSString *urlStr = obj;
            return [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        }
        return nil; // id here
    });
}

また

+ (URLTransformer)transformerToUrlWithString:(NSString *)urlStr
{
    return Block_copy(^(id obj){
        if ([obj isKindOfClass:NSString.class])
        {
            NSString *urlStr = obj;
            return [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        }
        return (id)nil; // **THIS LINE FAILS**
    });
}

2.

typedef なしでブロックを返すには、同様の構文を使用して関数ポインターを返すことができます

+ (id (^)(id))transformerToUrlWithString:(NSString *)urlStr;

ここからより多くの例を確認できます。

Block_copyPS: ObjC コードでは避けるべき[block copy]です。

PS2: ARC を使用する必要があり (それ以外の場合は非常に多くのリークが発生します)、ブロックを明示的にコピーする必要はありません (99% のケースで、これを含みます)。

idPS3:できるだけ避けるべきなので、ブロックはtypedef NSURL *(^URLTransformer)(NSString *);

于 2013-08-22T01:08:17.777 に答える
2

typedef次のように回避できます。

@interface Blah : NSObject
+(id (^)(id)) blockret;
@end

@implementation Blah
+(id (^)(id)) blockret {
    return ^(id obj) {
        return @"helo";
    };
}
@end

あなたのブロックのタイプはid (^)(id)- それはプラスの後の括弧に入るものです.

于 2013-08-22T01:08:36.577 に答える