我刚刚开始攀登Objective C学习曲线(使用Nerd Ranch iOS编程书).
基于我从其他语言中了解的关于在一行中"嵌套"多个执行的内容,我假设我可以改变:
NSString* descriptionString = [[NSString alloc] initWithFormat:@"%@", possesionName]
Run Code Online (Sandbox Code Playgroud)
有两行版本:
NSString* descriptionString = [NSString alloc];
[descriptionString initWithFormat:@"%@", possesionName]
Run Code Online (Sandbox Code Playgroud)
但似乎第二次尝试引发了一个例外
2012-01-22 18:25:09.753 RandomPossessions[4183:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -length only defined for abstract class. Define -[NSPlaceholderString length]!'
Run Code Online (Sandbox Code Playgroud)
有人能帮助我理解我在这里做错了什么吗?非常感谢提前.
PS.如果这是Objective C消息的工作方式,你必须让alloc和init在一行中让我知道 - 我假设这只是一组函数,可以一次执行,也可以一个接一个地执行.
Den*_*cht 10
两个版本之间的一个重要区别(它们并不完全相同)是在第一个版本中,您使用initWithFormat变量descriptionString的结果,alloc而在第二个版本中使用结果.如果您将代码更改为
NSString* descriptionString = [NSString alloc];
descriptionString = [descriptionString initWithFormat:@"%@", possesionName]
Run Code Online (Sandbox Code Playgroud)
一切都应该好了.指定返回的对象在被调用alloc某个init方法之前不应被视为已初始化和有效,并且init可能返回其他内容.
该alloc方法将为新对象分配内存。但该init方法可能会丢弃该内存并返回一个完全不同的对象。或者它可能会回来nil。self = [super init]这就是为什么在重写方法时必须始终这样做的原因init。
NSString是一个一直在做这种事情的类。
我不太确定为什么会发生异常,但我相信这可能是 ARC 在两行代码之间注入代码或类似的东西。不管是什么,某些东西正在尝试对从未初始化的分配对象进行操作,这是一个可能导致各种问题的巨大问题。认为自己很幸运它抛出了异常,有时它不会。
该NSString课程实际上可能不是真正的课程。它可能几乎不包含任何方法,也几乎不包含变量。它所拥有的只是一堆工厂方法来创建其他类的“真实”字符串对象,这是使用诸如initWithFormat:. 因此,根据长期约定,alloc/init 必须始终在单个语句中完成,并且通常出于性能原因,在少数地方,某些内容将依赖于使用此约定。
基本上,objective-c 是一种你不需要确切知道对象内部发生了什么的语言。您只需要知道可以向对象发送哪些消息以及它将如何响应。其他任何行为都是未定义的行为,即使您了解其工作原理,它也可能会发生更改,恕不另行通知。有时,行为会根据完全不合逻辑的情况而改变,例如,您可能期望“复制”方法为您提供发送到的对象的副本,虽然这是默认行为,但在很多情况下它实际上只会返回相同的对象,但内存管理标志略有不同。这是因为类的内部逻辑知道返回同一对象比返回实际副本要快得多并且实际上相同。
我的理解是copy发送给NSString可能会返回一个新的对象,也可能会返回它本身。这取决于实际使用的是哪个 NSString 子类,甚至没有任何关于存在哪些子类的文档,更不用说它们是如何实现的了。您需要知道的是,它将copy返回一个指向对象的指针,该对象可以完全安全地视为副本,即使它可能不是。
在像 Objective-C 这样的“正确的”面向对象语言中,对象是“黑匣子”,它们可以随时以任何原因智能地改变其内部行为,但它们的外部行为始终保持不变。
关于避免嵌套... Objective-C 的编码风格通常确实需要大量嵌套,否则您将编写 10 行代码,而实际上只需要 1 行代码。方括号语法特别适合嵌套,而不会让代码变得混乱。
根据经验,我打开 Xcode 的“列页面指南”功能,并将其设置为 120 个字符。如果代码行超过该宽度,那么我会考虑将其分成多行。但通常情况下,排很长的队比排三个短队更干净。
对此要务实。:)