目标c“您是否忘记嵌套alloc和init?"

目标c“您是否忘记嵌套alloc和init?

问题描述:

我刚刚开始学习Objective C学习曲线(使用Nerd Ranch iOS编程书).

I am just starting climbing the Objective C learning curve (using Nerd Ranch iOS programming book).

根据我从其他语言中学到的关于在一行中嵌套"多个执行的知识,我认为我可以更改:

Based on what I have know from other languages about "nesting" multiple executions within one line I assumed that I can alter:

NSString* descriptionString = [[NSString alloc] initWithFormat:@"%@", possesionName] 

具有两行版本:

NSString* descriptionString = [NSString alloc];
[descriptionString initWithFormat:@"%@", possesionName] 

但是第二次尝试似乎引发了异常

but it seems that the second attempt raises an exception

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]!'

有人可以帮助我了解我在这里做错了什么吗?提前谢谢.

Could someone help me understand what exactly I am doing wrong here? Thanks a lot in advance.

PS.如果这是目标C消息工作的方式,并且您必须在一行中进行alloc和init,那就让我知道-我认为这只是一组函数,可以一次执行两次,也可以一次又一次执行.

PS. If this is a way Objective C messages work and you have to make alloc and init in one line just let me know - I assumed this is just a set of functions that either can be executed two in one go or one after another.

alloc方法将为新对象分配内存.但是init方法可能会丢弃该内存并返回完全不同的对象.否则可能返回nil.这就是为什么在覆盖init方法时必须始终执行self = [super init]的原因.

The alloc method will allocate memory for a new object. But the init method might throw away that memory and return a completely different object. Or it might return nil. This is why you must always do self = [super init] when you override an init method.

NSString是一类经常执行此类操作的类.

NSString is one class that does this kind of thing all the time.

我不确定为什么会发生异常,但是我相信这可能是ARC在您的两行代码或类似代码之间注入了代码.不管是什么,有些事情正在试图作用于从未初始化的分配对象上,这是一个巨大问题,可能导致各种问题.认为自己很幸运,它引发了异常,有时不会.

I'm not exactly sure why the exception is happening, but I believe it could be ARC injecting code in between your two lines of code or something similar. Whatever it is, something is trying to act on the allocated object that has never been initialised, and this is a huge problem that can lead to all kinds of issues. Consider yourself lucky it threw an exception, sometimes it wont.

NSString类实际上可能不是真正的类.它可能几乎不包含任何方法,也几乎不包含任何变量.它所拥有的只是一堆工厂方法来创建其他类的真实"字符串对象,而这是使用initWithFormat:之类的方法完成的.因此,根据长期的惯例,必须始终在单个语句中完成alloc/init,并且在少数地方,通常出于性能原因,有些东西会依赖于所使用的惯例.

The NSString class might not actually be a real class. It may contain almost no methods and almost no variables. All it has is a bunch of factory methods to create "real" string objects of some other class, and this is done using methods like initWithFormat:. So, by long standing convention alloc/init must always be done in a single statement and there are a handful of places where, usually for performance reasons, something will rely on this convention being used.

基本上,objective-c是一种语言,您无需完全了解对象内部的情况.您只需要知道可以向对象发送哪些消息,以及消息将如何响应.任何其他行为都是不确定的行为,即使您了解其工作方式,也可能随时更改,恕不另行通知.有时,行为会因完全不合逻辑的情况而发生变化,例如,您可能希望复制"方法为您提供将其发送到的对象的副本,虽然这是默认行为,但在许多情况下,它会实际上只会返回带有稍微不同的内存管理标志的同一对象.这是因为该类的内部逻辑知道返回同一对象要比返回实际副本快得多,并且实际上是完全相同的.

Basically, objective-c is a language where you don't need to know exactly what is going on inside an object. You just need to know what messages can be sent to an object, and how it will respond. Anything else is undefined behaviour and even if you learn how it works, it is subject to change without notice. Sometimes the behaviour will change depending on circumstances that are completely illogical, for example you might expect the "copy" method to give you a copy of the object you send it to, and while this is the default behaviour, there are many cases where it will actually just return the same object with slightly different memory management flags. This is because the internal logic of the class knows that returning the same object is much faster and effectively identical to returning an actual copy.

我的理解是copy发送到NSString可能返回一个新对象,也可能返回自己.这取决于实际使用的是哪个NSString子类,甚至还没有关于子类存在的任何文档,更不用说如何实现它们了.您需要知道的是,copy将返回一个对象的指针,即使该对象可能不是副本,也可以完全安全地将其视为副本.

My understanding is copy sent to NSString may return a new object, or it may return itself. It depends on which NSString subclass is actually being used, and there isn't even any documentation for what subclasses exist, let alone how they're implemented. All you need to know, is that copy will return a pointer to an object that is perfectly safe to treat as if it was a copy even though it might not be.

在像Objective-C这样的适当"面向对象的语言中,对象是黑匣子",它们可以随时出于任何原因智能地更改其内部行为,但是它们的外部行为始终保持不变.

In a "proper" object oriented language like Objective-C, objects are "black boxes" which can intelligently change their internal behaviour at any time for any reason, but their external behaviour always remains the same.

关于避免嵌套... Objective-C的编码风格经常需要大量的嵌套,否则,当真正需要1行时,您将编写10行代码.方括号语法特别适合嵌套而不会使您的代码混乱.

With regard to avoiding nesting... The coding style for Objective-C often does require extensive nesting, or else you'll be writing 10 lines of code when only 1 is really needed. The square brace syntax is particularly suited to nesting without making your code messy.

根据经验,我打开Xcode的列的页面向导"功能,并将其设置为120个字符.如果代码行超过该宽度,那么我将考虑将其分成多行.但通常情况下,拥有一条长线要比三条短线更干净.

As a rule of thumb, I turn on Xcode's "Page Guide at column" feature, and set it to 120 characters. If the line of code exceeds that width then I'll think about breaking it into multiple lines. But often it's cleaner to have a really long line than three short lines.

务实. :)