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)——这就是进入后括号加上。