Ios &引用;缺少“块类型说明符”;重构代码后出现编译错误,但在重构前确认
我有一些代码可以下载图像并在块中分配它。代码目前运行正常,但我想将其重构为一个单独的方法,但重构后我会出现编译错误 这是编译并运行成功分配下载映像的原始代码:Ios &引用;缺少“块类型说明符”;重构代码后出现编译错误,但在重构前确认,ios,objective-c,objective-c-blocks,Ios,Objective C,Objective C Blocks,我有一些代码可以下载图像并在块中分配它。代码目前运行正常,但我想将其重构为一个单独的方法,但重构后我会出现编译错误 这是编译并运行成功分配下载映像的原始代码: - (void) someMethod { … MyObject* object = [[MyObject alloc] init]; [self.objects addObject: object]; NSString* graphRequest = [NSString stringWithFormat:@"%
- (void) someMethod
{
…
MyObject* object = [[MyObject alloc] init];
[self.objects addObject: object];
NSString* graphRequest = [NSString stringWithFormat:@"%@%@%@", @"https://graph.facebook.com/",
fbid,
@"/picture?type=square"];
FBRequest *fbRequest = [FBRequest requestForGraphPath: graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection *connection, id result, NSError *theError)
{
NSDictionary<FBGraphObject> *dict = (NSDictionary<FBGraphObject> *) result;
if (dict)
{
NSString* urlAsString = [dict objectForKey:@"id"];
if ([urlAsString length] > 0)
{
NSURL *url = [NSURL URLWithString: urlAsString];
NSData *data = [NSData dataWithContentsOfURL:url];
object.image = [UIImage imageWithData:data];
}
}
}];
}
-(void)someMethod
{
…
MyObject*object=[[MyObject alloc]init];
[self.objects addObject:object];
NSString*graphRequest=[NSString stringWithFormat:@“%@%@%@”,@”https://graph.facebook.com/",
fbid,
@“/picture?type=square”];
FBRequest*FBRequest=[FBRequestRequestForGraphPath:graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection*连接,id结果,N错误*theError)
{
NSDictionary*dict=(NSDictionary*)结果;
if(dict)
{
NSString*urlAsString=[dict objectForKey:@“id”];
如果([urlAsString长度]>0)
{
NSURL*url=[NSURL URLWithString:URLAString];
NSData*data=[NSData dataWithContentsOfURL:url];
object.image=[UIImage imageWithData:data];
}
}
}];
}
如果我将其重构为以下内容,则会出现编译错误
- (void) someMethod
{
…
MyObject* object = [[MyObject alloc] init];
[self.objects addObject: object];
[self fetchFbImage: object.image forFbid:fbid];
}
- (void) fetchFbImage:(UIImage*) targetImage forFbid:(NSString*) fbid
{
NSString* graphRequest = [NSString stringWithFormat:@"%@%@%@", @"https://graph.facebook.com/",
fbid,
@"/picture?type=square"];
FBRequest *fbRequest = [FBRequest requestForGraphPath: graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection *connection, id result, NSError *theError)
{
NSDictionary<FBGraphObject> *dict = (NSDictionary<FBGraphObject> *) result;
if (dict)
{
NSString* urlAsString = [dict objectForKey:@"id"];
if ([urlAsString length] > 0)
{
NSURL *url = [NSURL URLWithString: urlAsString];
NSData *data = [NSData dataWithContentsOfURL:url];
targetImage = [UIImage imageWithData:data];
}
}
}];
}
-(void)someMethod
{
…
MyObject*object=[[MyObject alloc]init];
[self.objects addObject:object];
[self-fetchFbImage:object.image forFbid:fbid];
}
-(void)fetchFbImage:(UIImage*)targetImage forFbid:(NSString*)fbid
{
NSString*graphRequest=[NSString stringWithFormat:@“%@%@%@”,@”https://graph.facebook.com/",
fbid,
@“/picture?type=square”];
FBRequest*FBRequest=[FBRequestRequestForGraphPath:graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection*连接,id结果,N错误*theError)
{
NSDictionary*dict=(NSDictionary*)结果;
if(dict)
{
NSString*urlAsString=[dict objectForKey:@“id”];
如果([urlAsString长度]>0)
{
NSURL*url=[NSURL URLWithString:URLAString];
NSData*data=[NSData dataWithContentsOfURL:url];
targetImage=[UIImage imageWithData:data];
}
}
}];
}
编译错误是分配到targetImage的行“变量不可分配(缺少块类型说明符)”
我应该在哪里添加块类型说明符?为什么在重构之后而不是重构之前会出现问题
感谢您的第一种方法(无需重构),您可以将图像设置为object,因为您对对象有引用,所以您做到了
object.image = [UIImage imageWithData:data];
但是在重构之后,您不能以您正在做的方式设置图像,您还应该发送对象
- (void) someMethod
{
…
MyObject* object = [[MyObject alloc] init];
[self.objects addObject: object];
[self fetchFbImageForObj:object forFbid:fbid];
}
- (void) fetchFbImageForObject:(MyObject*)object forFbid:(NSString*) fbid
{
NSString* graphRequest = [NSString stringWithFormat:@"%@%@%@", @"https://graph.facebook.com/",
fbid,
@"/picture?type=square"];
FBRequest *fbRequest = [FBRequest requestForGraphPath: graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection *connection, id result, NSError *theError)
{
NSDictionary<FBGraphObject> *dict = (NSDictionary<FBGraphObject> *) result;
if (dict)
{
NSString* urlAsString = [dict objectForKey:@"id"];
if ([urlAsString length] > 0)
{
NSURL *url = [NSURL URLWithString: urlAsString];
NSData *data = [NSData dataWithContentsOfURL:url];
object.image = [UIImage imageWithData:data];
}
}
}];
}
-(void)someMethod
{
…
MyObject*object=[[MyObject alloc]init];
[self.objects addObject:object];
[自取fbimageforobj:objectforfbid:fbid];
}
-(void)fetchFbImageForObject:(MyObject*)对象forFbid:(NSString*)fbid
{
NSString*graphRequest=[NSString stringWithFormat:@“%@%@%@”,@”https://graph.facebook.com/",
fbid,
@“/picture?type=square”];
FBRequest*FBRequest=[FBRequestRequestForGraphPath:graphRequest];
[fbRequest startWithCompletionHandler:
^(FBRequestConnection*连接,id结果,N错误*theError)
{
NSDictionary*dict=(NSDictionary*)结果;
if(dict)
{
NSString*urlAsString=[dict objectForKey:@“id”];
如果([urlAsString长度]>0)
{
NSURL*url=[NSURL URLWithString:URLAString];
NSData*data=[NSData dataWithContentsOfURL:url];
object.image=[UIImage imageWithData:data];
}
}
}];
}
试试看。如果有任何错误或什么,请在下面评论。您似乎对Objective-C中的参数是如何工作的感到困惑 在原始代码中,您有:
MyObject* object = [[MyObject alloc] init];
它将对象
声明为方法的局部变量。然后在块内写入:
object.image = [UIImage imageWithData:data];
targetImage = [UIImage imageWithData:data];
因此,块引用局部变量object
,并且(由于声明中没有\uu block
属性),块获取变量内容的常量副本。这很好,因为您没有更改object
中的内容,该对象是对MyObject
实例的引用,而是在该实例上调用一个方法,该方法会更改该实例的内部状态。[*]
现在让我们看看您的重构。您删除了someMethod
的代码块,并将其放置在新方法fetchFbImage
中。在someMethod
中调用fetchFbImage
:
[self fetchFbImage:object.image forFbid:fbid];
这会将object.image
的当前值传递给方法,而不会以可在fetchFbImage
中指定的方式传递属性。参数targetImage
的类型是UIImage*
-对UIImage
的引用-它不是“类型为UIImage*
的属性”-不能有此类类型的参数,属性不能仅传递其值或对具有属性的对象的引用
调用方法时,每个参数实际上是一个局部变量,初始化为传递的参数值,因此上述方法调用有效地执行:
UIImage *targetImage = object.image;
其中,targetImage
是fetchFbImage
范围内的局部变量,object
是somethod
范围内的局部变量
现在,在您编写的fetchFbImage
内的块中
- (void) fetchFbImage:(MyObject *)targetObject forFbid:(NSString *)fbid
{
...
targetObject.image = [UIImage imageWithData:data];
...
}
...
[self fetchFbImage:object forFbid:fbid];
typedef void (^ImageConsumer)(NSImage *image);
- (void) fetchFbImageForFbid:(NSString *)fbid completionHandler:(ImageConsumer)handler
handler([UIImage imageWithData:data]);
[self fetchFbImageForFbid:fbid
completionHandler:^(NSImage *image) { object.image = image; }
];