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