为什么NULL需要使用块进行类型转换?

时间:2014-09-01 05:50:00

标签: ios objective-c xcode uiimage objective-c-blocks

请参阅此方案:

@property (nonatomic,copy) UIImage * (^bgImageBlock)(void);

bgImageBlock块变量的定义:

objDrawing.bgImageBlock = ^(){
         return (UIImage *)NULL;
    };

bgImageBlock有返回类型UIImage,如果我像这样传递NULL:

objDrawing.bgImageBlock = ^(){
         return NULL;
    };

会给出编译时错误:Incompitable block pointer type assigning to UIImage.

然而,如果我采用简单的UIImage变量并将其赋值为NULL,那绝对没问题。那么为什么在Block的情况下它不能在没有类型转换的情况下接受NULL。 ?

3 个答案:

答案 0 :(得分:2)

如果您没有明确告诉它,编译器会根据您返回的对象类型推断块返回类型。所以,在这种情况下:

objDrawing.bgImageBlock = ^(){
     return NULL;
};

...我认为它看到NULL并推断您的广告素材的返回类型为void *,类型为NULL。这与您的属性类型不匹配,因此编译器会抱怨。 (请注意,错误是关于&#34;块指针类型&#34 ;;它是块属性声明与您尝试存储在其中的块之间的不匹配。)< / p>

如果您明确告诉它您的类型,您应该能够使用简单的NULL返回:

objDrawing.bgImageBlock = ^UIImage*(){
     return NULL;
};

从返回类型中推断出块类型记录为in the Clang documentation

  

返回类型是可选的,可以从return语句中推断出来。如果return语句返回一个值,则它们都必须返回相同类型的值。如果没有返回值,则块的推断类型无效;否则它是返回语句值的类型。

返回类型的推断,以及编译器为您检查指针类型的事实,并且如果出现不匹配,则会产生错误,{{3 &#34; Objective-C&#34;的进展。 (参见标题为&#34的部分;返回类型推断&#34;)。

答案 1 :(得分:0)

您的区块需要UIImage*类型。但是,NULL是一个指针,它只是不能识别它指向UIImage*类型的任何地方(不管它是什么)。巴姆,错误。

但是,您现在正在投射指针。它实际上并没有在运行时做任何事情。 它只是修改指向的类型,然后影响对结果值的后续操作。但实际指针值将通过演员表保持不变。

虽然实际的指针保持不变(但所有指向的值都没有),但它现在指向该块预期将返回的类型。一切都很好。 :)

答案 2 :(得分:0)

NULL的类型为void *,因此推断该块具有返回类型void *和非Objective-C-object指针类型(如void *)与Objective-C-object指针类型不兼容(如UIImage *)。相反,您应该使用nil,它也是一个空指针,但类型为id,它与所有Objective-C-object指针类型兼容。