gpt4 book ai didi

objective-c - 在 Objective C 中,为什么我可以在没有错误或警告的情况下将 NSArray 分配给 NSMutableArray?

转载 作者:太空狗 更新时间:2023-10-30 03:19:10 24 4
gpt4 key购买 nike

我对一种奇怪的行为感到不安,如下例所示:

NSMutableArray *a1 = [[NSMutableArray alloc] init]; // fine
NSMutableArray *a2 = [NSMutableArray array]; // fine, too

// compiler reports incompatible pointer types; good:
NSMutableArray *a3 = [[NSArray alloc] init];

// compiler says nothing and is happy to assign this!
NSMutableArray *a4 = [NSArray array];

NSArrayNSMutableArray 类的initarray 方法都返回id。然而,当我调用这些方法时的行为完全不同,而且 clang 让我愉快地将一个空的 NSArray 分配给一个 NSMutableArray 变量!

事实证明clang will automatically change the return type of some methods, including the init family, to instancetype ,因此能够在编译时确定 [[NSArray alloc] init] 返回一个 NSArray * 而不是 NSMutableArray *。但是这种检查根本不适用于 array 方法。

为什么?像我上一个示例这样的行不应该至少生成一个警告吗?为什么不将所有这些方法都声明为返回 instancetype?以后会变吗?


更新

好消息:从 iOS 7 开始,[NSArray array] 返回 instancetype,因此上面对 a4 的赋值也会产生警告。其他方法,如 arrayWithContentsOfFile:arrayWithContentsOfURL 仍然返回 id,但是......

最佳答案

But this check simply doesn't work with the array method. Why?

如您链接的文档所述,这是因为 -array 没有产生可识别的相关结果类型。 ObjC 是非常动态的——编译器不能保证 +array 的结果类型。它确实对某些方法做出了这种假设,因为命名约定定义明确(例如 +alloc-init+new -self 等)。因此,此实现简单地诉诸于命名约定。

编译器还会在您可能意想不到的地方验证一些命名约定:

@implementation NSArray (DEMO)

- (id)initStr
{
return [NSString new]; // << warning. RE: init prefix
}

@end

Shouldn't lines like my last example generate at least a warning? Why aren't all these methods declared as returning instancetype? Will it change in the future?

instancetype 大约在一年前推出(从外观上看)。一些 API 是几十年前编写的。我怀疑它会发生 -- 及时 -- 因为(如果使用得当)它可以指出现有代码中的很多问题。当然,这些更改会破坏现有构建(同样,如果在正确的位置声明,通常是很好的更正)。

所以记录错误并给工具和库几年的时间来更新。假设进行了更改,它可能会在主要操作系统更新时发生。

最好将它作为可选警告启用一段时间(在系统 header 的情况下)。当然,他们仍然可以使用它来向后兼容新 API 的旧编译器。

此外,可以通过一个简单的 typedef 很容易地改造此更改(并不是说早期的编译器会理解 idinstancetype 之间的语义差异)。 typedef 的一个问题是它是一个全局声明——编译器可以将单词/修饰符/属性限制在给定的范围内,而不会通过添加全局 typedef 来模拟关键字。 Apple 的 GCC 可能永远不支持 instancetype,因此为 Apple 的 GCC 引入它的合乎逻辑的方式可能是 id 的全局 typedef,这可能会导致问题对于某些人(如果采用该路线,则没有语义上的好处)。请注意,Apple 过去也进行过类似的重大更改。

关于objective-c - 在 Objective C 中,为什么我可以在没有错误或警告的情况下将 NSArray 分配给 NSMutableArray?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15248437/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com