Objective c 理解NSString的initWithBytes

Objective c 理解NSString的initWithBytes,objective-c,Objective C,假设“someData”是一个NSMutableData,其中包含一些字节的数据 如果我写以下内容: NSString *someString = [NSString string]; [someString initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding]; 第二行给出了一个“无法识别的选择器发送到实例”错误 但如果我写: NSString *someSt

假设“someData”是一个NSMutableData,其中包含一些字节的数据

如果我写以下内容:

NSString *someString = [NSString string];
[someString initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding];
第二行给出了一个“无法识别的选择器发送到实例”错误

但如果我写:

NSString *someString=[[NSString alloc] initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding];
然后它就起作用了。前一种方法不起作用有什么原因吗?不使用“alloc”(事先创建一些字符串)可以完成吗


谢谢。

第一种方法创建一个已初始化的空自动删除字符串,然后再次尝试初始化该字符串。第二种方法分配内存,然后对其进行适当的初始化。请注意,第二种方法不会自动释放创建的字符串,因此调用范围仍然负责。如果需要,您可以将第二种方式包装在NSString类别上的便利方法中,以获得与第一种方式更相似的内容:

@interface NSString (stringWithBytes)

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding;

@end

@implementation NSString (stringWithBytes)

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding {
    NSString * aString = [[NSString alloc] initWithBytes:bytes length:length encoding:encoding];
    return [aString autorelease];
}

@end

原因是
[NSString]
返回的对象不响应选择器
-initWithBytes:length:encoding:
。这是因为NSString是不可变的-一旦创建,就不能更改。方法
-string
利用了这一点,只提供了一个对空常量字符串(在编译时创建)的引用

不仅如此,NSString还是一个类集群。这意味着,当您请求NSString时,实际上可能会得到它的一个子类的实例。我的猜测是,您将得到一个子类,该子类重写了
-initWithBytes:length:encoding:
,以引发异常,因为向编译时创建的常量字符串发送init方法没有意义


在第二种情况下,您将在运行时创建一个全新的NSString,然后向其发送一条init消息。这很好。请注意,由于它是一个类群集,init方法返回的字符串可能与
-alloc

创建的字符串不同。您应该阅读“”的基础知识。您的问题应该是关于
alloc
init
的,而不是这个
NSString
方法。它们不应该是类方法吗?啊,很好。我将编辑以匹配。直接输入代码而不是从Xcode粘贴似乎总是会导致遗漏一些内容。我在手机上输入了很多答案。真是个奇迹,我居然有名声,我想我明白了。前一种情况是在编译时创建NSString。一旦创建,就不能重新初始化。后一种情况是在运行时创建一个string对象,并在同一行对其进行初始化。但是,将第一种情况下的第二行替换为[someString init]不会导致错误。也许这是类集群的问题。