返回没有类型定义的块的Objective-C方法的语法/签名是什么?

时间:2022-11-15 22:33:18

I defined a block that takes an NSString and returns a NSURL for that string:

我定义了一个块,它接受一个NSString并为该字符串返回一个NSURL:

id (^)(id obj)

I've used typedef to make it a block with a name:

我用typedef把它做成一个有名字的块:

typedef id (^URLTransformer)(id);

And the following method does not work:

而以下方法不起作用:

+ (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**
    });
}

Error:

错误:

Return type 'void *' must match previous return type 'id' when block literal has unspecified explicit return type

当块文字具有未指定的显式返回类型时,返回类型“void *”必须与之前的返回类型“id”匹配

My question is: 1. how to correctly implement the method 2. how to implement the method without typedef URLTransformer?

我的问题是:1。如何正确实现方法2。如何在没有typedef URLTransformer的情况下实现该方法?

Thanks

谢谢

2 个解决方案

#1


3  

1.

1。

You can either cast it to id or add type to block. I asked similar question before and quote from the answer

您可以将它转换为id,也可以将类型添加到block。我之前问过类似的问题,并引用了答案。

The correct way to remove that error is to provide a return type for the block literal:

删除该错误的正确方法是为块文字提供返回类型:

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

in your case

在你的情况中

+ (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
    });
}

or

+ (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.

2。

To return block without typedef you can use similar syntax to return function pointer

要返回没有类型定义的块,可以使用类似的语法返回函数指针

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

You can check more example from here.

你可以在这里查看更多的例子。

PS: You should avoid Block_copy in ObjC code, use [block copy].

在ObjC代码中应该避免Block_copy,使用[block copy]。

PS2: You mush be using ARC (otherwise so many leaks) and you don't need to copy block explicitly (in 99% of the cases, which includes this one).

PS2:您必须使用ARC(否则会有很多泄漏),并且不需要显式地复制block(99%的情况下,包括这个)。

PS3: Your should avoid id as much as possible, so your block should be typedef NSURL *(^URLTransformer)(NSString *);

PS3:你应该尽可能避免id,因此你的块应该是typedef NSURL *(^ URLTransformer)(NSString *);

#2


2  

You can avoid typedef like this:

你可以避免这样的类型定义:

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

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

The type of your block is id (^)(id) - that's what goes into parentheses after the plus.

你的块类型id(^)(id)——这就是进入后括号加上。

#1


3  

1.

1。

You can either cast it to id or add type to block. I asked similar question before and quote from the answer

您可以将它转换为id,也可以将类型添加到block。我之前问过类似的问题,并引用了答案。

The correct way to remove that error is to provide a return type for the block literal:

删除该错误的正确方法是为块文字提供返回类型:

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

in your case

在你的情况中

+ (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
    });
}

or

+ (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.

2。

To return block without typedef you can use similar syntax to return function pointer

要返回没有类型定义的块,可以使用类似的语法返回函数指针

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

You can check more example from here.

你可以在这里查看更多的例子。

PS: You should avoid Block_copy in ObjC code, use [block copy].

在ObjC代码中应该避免Block_copy,使用[block copy]。

PS2: You mush be using ARC (otherwise so many leaks) and you don't need to copy block explicitly (in 99% of the cases, which includes this one).

PS2:您必须使用ARC(否则会有很多泄漏),并且不需要显式地复制block(99%的情况下,包括这个)。

PS3: Your should avoid id as much as possible, so your block should be typedef NSURL *(^URLTransformer)(NSString *);

PS3:你应该尽可能避免id,因此你的块应该是typedef NSURL *(^ URLTransformer)(NSString *);

#2


2  

You can avoid typedef like this:

你可以避免这样的类型定义:

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

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

The type of your block is id (^)(id) - that's what goes into parentheses after the plus.

你的块类型id(^)(id)——这就是进入后括号加上。