Objective c NSString和NSMutableString方法以及通过mutableCopy进行强制转换 来自C++背景,我很惊讶我必须编写下面的代码来避免警告: NSMutableString *foobar = [@"foobar" mutableCopy]; // line 1 foobar = [[foobar capitalizedString] mutableCopy]; // line 2 foobar = [foobar capitalizedString]; // line 2

Objective c NSString和NSMutableString方法以及通过mutableCopy进行强制转换 来自C++背景,我很惊讶我必须编写下面的代码来避免警告: NSMutableString *foobar = [@"foobar" mutableCopy]; // line 1 foobar = [[foobar capitalizedString] mutableCopy]; // line 2 foobar = [foobar capitalizedString]; // line 2,objective-c,nsstring,Objective C,Nsstring,第1行对我来说似乎很正常:不能直接将常量字符串转换为字符串 第2行让我困惑:capitalizedString是一个属于NSString并返回NSString的方法。因此,为了将其影响为NSMutableString,您必须通过mutableCopy“重铸”它 但为什么NSMutableString中的capitalizedString没有像“-(NSMutableString*)capitalizedString那样重载 如果是这样的话,我们可以简单地编写以下内容,而不需要任何警告: NSMu

第1行对我来说似乎很正常:不能直接将常量字符串转换为字符串

第2行让我困惑:capitalizedString是一个属于NSString并返回NSString的方法。因此,为了将其影响为NSMutableString,您必须通过mutableCopy“重铸”它

但为什么NSMutableString中的capitalizedString没有像“-(NSMutableString*)capitalizedString那样重载

如果是这样的话,我们可以简单地编写以下内容,而不需要任何警告:

NSMutableString *foobar = [@"foobar" mutableCopy]; // line 1
foobar = [[foobar capitalizedString] mutableCopy]; // line 2
foobar = [foobar capitalizedString]; // line 2
PS:我知道我可以在一行中同时写两行,但这是一个例子。

根据
capitalizedString
的内部实现,方法如下所示,其中包含
readonly
copy
属性

@property(readonly, copy) NSString *capitalizedString
因此,如果调用
capitalizedString
方法,它将返回
NSString
对象。因此,为了将其影响到
NSMutableString
对象,需要使用
mutableCopy

,因为
capitalizedString
方法的内部实现类似于下面包含
readonly
copy
属性的方法

@property(readonly, copy) NSString *capitalizedString

因此,如果调用
capitalizedString
方法,它将返回
NSString
对象。因此,为了将其影响到
NSMutableString
对象,需要使用
mutableCopy

[foobar capitalizedString]
返回一个
NSString
,但
foobar
已声明
NSMutableString
,因此需要创建一个可变版本以分配

NSString *foobar = @"foobar";
foobar = [foobar capitalizedString];
// Create a new instance `NSString` instance and assigns it to the same `NSString` pointer `foobar`.

为什么要使用
NSMutableString
?在Objective-C中,使用可变对象并不常用/需要。

[foobar capitalizedString]
返回一个
NSString
,但
foobar
被声明为
NSMutableString
,因此需要创建可变版本才能分配

NSString *foobar = @"foobar";
foobar = [foobar capitalizedString];
// Create a new instance `NSString` instance and assigns it to the same `NSString` pointer `foobar`.
为什么要使用
NSMutableString
?在Objective-C中,不常用/不需要使用可变对象

因此,为了将其影响为NSMutableString,您必须通过mutableCopy“重铸”它

<>代码> MutabelPope<代码>不是C++中的“重铸”。它创建了一个可变副本。ObjC中有重铸,但不是这样。这一区别很重要,因为“重铸”意味着你只拿了一个物体,而只是以不同的方式对待它
mutableCopy
创建一个具有内存管理含义的新对象。(这些问题现在主要由ARC处理,但它们对于理解正在发生的事情仍然很重要。)

但为什么NSMutableString中的capitalizedString没有像“-(NSMutableString*)capitalizedString那样重载

Objective-C没有重载。所以这是不可能的,即使它是可取的。这是否真的令人满意是一个有趣的问题。在某些用例中,它可能更方便。在其他用例中,这就不那么方便了(不可变字符串具有可供可变字符串丢失的优化,因此如果我想要这些优化,我必须再次复制字符串以使其不可变)。但这是毫无意义的;重载是不可能的。因此,要得到您所要求的,您必须创建
-mutableCapitalizedString
,就像我们有
copy
mutableCopy
一样。(那太傻了,因为
大写字符串
非常罕见。)

正如@Zaph指出的,
NSMutableString
在ObjC中有些不常见。也就是说,您的问题也适用于
-sortedarrayingselector:
,因此基本问题是有效的

值得注意的是,Swift确实有重载,您所描述的内容可以在Swift中完成(尽管它会破坏类型推断,所以在大多数情况下可能会很烦人)。但斯威夫特认为有必要增加过载。ObjC就是没有

因此,为了将其影响为NSMutableString,您必须通过mutableCopy“重铸”它

<>代码> MutabelPope<代码>不是C++中的“重铸”。它创建了一个可变副本。ObjC中有重铸,但不是这样。这一区别很重要,因为“重铸”意味着你只拿了一个物体,而只是以不同的方式对待它
mutableCopy
创建一个具有内存管理含义的新对象。(这些问题现在主要由ARC处理,但它们对于理解正在发生的事情仍然很重要。)

但为什么NSMutableString中的capitalizedString没有像“-(NSMutableString*)capitalizedString那样重载

Objective-C没有重载。所以这是不可能的,即使它是可取的。这是否真的令人满意是一个有趣的问题。在某些用例中,它可能更方便。在其他用例中,这就不那么方便了(不可变字符串具有可供可变字符串丢失的优化,因此如果我想要这些优化,我必须再次复制字符串以使其不可变)。但这是毫无意义的;重载是不可能的。因此,要得到您所要求的,您必须创建
-mutableCapitalizedString
,就像我们有
copy
mutableCopy
一样。(那太傻了,因为
大写字符串
非常罕见。)

正如@Zaph指出的,
NSMutableString
在ObjC中有些不常见。也就是说,您的问题也适用于
-sortedarrayingselector:
,因此基本问题是有效的

值得注意的是,Swift确实有重载,您所描述的内容可以在Swift中完成(尽管它会破坏类型推断,所以在大多数情况下可能会很烦人)。但斯威夫特认为有必要增加过载。ObjC只是没有它们。

我将NSString视为“const char*/const std::string”,将NSMutableString视为“char*/std::str”