不兼容的指针类型,初始化'SubClass * __ strong',类型为'BaseClass *' [英] Incompatible pointer types initializing 'SubClass *__strong' with an expression of type'BaseClass *'

查看:438
本文介绍了不兼容的指针类型,初始化'SubClass * __ strong',类型为'BaseClass *'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在objective-C中,为什么我们不能 alloc + init / code>一个具有超类的基类对象,同时我们可以使用超类的构造函数来初始化



下面是一些代码: p>

s1 可以非常舒适地创建。

  NSMutableString * s1 = [NSString string]; 
NSLog(@%@,s1);

s2 s3 不能并且给出警告



不兼容的指针类型用表达式初始化SubClass * __ strong类型'BaseClass *'

  NSMutableString * s2 = [[NSString alloc] init]; 
NSLog(@%@,s2);

NSMutableString * s3 = [NSString new];
NSLog(@%@,s3);

//这里没有警告。
id mem = [NSString alloc];
NSMutableString * s4 = [mem init];
NSLog(@%@,s4);

当我们将alloc + init断开为两个不同的语句时会发生什么?

解决方案

答案可以在


相关结果类型

strong>



根据Cocoa约定,具有某些名称
(init,alloc等)的Objective-C方法总是返回
的实例接收类的类型。这样的方法被称为具有相关
结果类型,意味着发送到这些方法中的一个的消息将
具有与接收器类的实例相同的静态类型。


因此在

  NSMutableString * s2 = [[ NSString alloc] init]; 

右侧的类型实际上是 NSString * ,而不是 id ,并将其分配给 NSMutableString * ,则会产生一个不兼容的指针类型警告。 / p>

另一方面, string 方法

  NSMutableString * s1 = [NSString string]; 

没有相关结果类型,所以它只返回可以分配给 NSMutableString *



单独的语句仅在使用 id 作为中间类型时抑制警告。使用 NSString NSMutableString ,您仍会收到警告:

  NSString * tmp4 = [NSString alloc]; 
NSMutableString * s4 = [tmp4 init]; //< - Warning here

NSMutableString * tmp5 = [NSString alloc]; //< - Warning here
NSMutableString * s5 = [tmp5 init];






根据文档,相关结果类型,如果其返回类型与其类的类型兼容并且如果:




  • 第一个单词是alloc new,并且方法是类方法,或

  • 第一个词是autorelease,init,retain或self,并且方法是一个实例方法。


In objective-C, why we can not alloc+init or new a base-class object with super-class, whilst we can use constructor of super-class to initialize?

Below is some code :

s1 can be created quite comfortably.

NSMutableString *s1=[NSString string];
NSLog(@"%@",s1);

But s2 and s3 can not be, and gives a warning

Incompatible pointer types initializing 'SubClass *__strong' with an expression of type'BaseClass *'

NSMutableString *s2=[[NSString alloc] init];
NSLog(@"%@",s2);

NSMutableString *s3=[NSString new];
NSLog(@"%@",s3);

//here no warning.
id mem=[NSString alloc];
NSMutableString *s4=[mem init];
NSLog(@"%@",s4);

What happens when we break alloc + init to two different statement?

解决方案

The answer can be found in Objective-C Features of the Clang 3.3 documentation:

Related result types

According to Cocoa conventions, Objective-C methods with certain names ("init", "alloc", etc.) always return objects that are an instance of the receiving class’s type. Such methods are said to have a "related result type", meaning that a message send to one of these methods will have the same static type as an instance of the receiver class.

Therefore in

NSMutableString *s2 = [[NSString alloc] init];

the type of the right hand side is actually NSString * and not id, and assigning that to an NSMutableString * gives a "Incompatible pointer types" warning.

On the other hand, the string method in

NSMutableString *s1 = [NSString string];

does not have a "related result type", so it just returns an id which can be assigned to the NSMutableString *.

Breaking alloc/init into separate statements suppresses the warning only if you use id as intermediate type. With NSString or NSMutableString you still get the warnings:

NSString *tmp4 = [NSString alloc];
NSMutableString *s4 = [tmp4 init]; // <-- Warning here

NSMutableString *tmp5 = [NSString alloc]; // <-- Warning here
NSMutableString *s5 = [tmp5 init];


According to the documentation, a method has a "related result type" if its return type is compatible with the type of its class and if:

  • the first word is "alloc" or "new", and the method is a class method, or
  • the first word is "autorelease", "init", "retain", or "self", and the method is an instance method.

这篇关于不兼容的指针类型,初始化'SubClass * __ strong',类型为'BaseClass *'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆