0

我将如何转这个:

xmlObject *system_domain  = [xmlObject alloc] 
xmlObject *system_description = [xmlObject alloc]
xmlObject *system_type = [xmlObject alloc]

变成我只需要编写一次 xmlObject 和 [xmlObject alloc] 的东西。

xmlObject *system_domain, *system_description, *system_type = [xmlObject alloc]

这使它们都成为 xmlObjects,但不会分配每一个。任何帮助将非常感激。

4

2 回答 2

2

如果你有一组相关的对象,并且能够迭代它们比能够简洁地访问它们更重要,你应该把它们放在一个集合中:

NSMutableDictionary *system_info = [NSMutableDictionary dictionary];
for (id key in @[@"domain", @"description", @"type"]) {
  system_info[key] = [xmlObject alloc];
}

然后,而不是system_dictionary你使用system_info[@"dictionary"]. (如果这很重要,您甚至可以使用 KVC 使事情更简洁。)当然,如果这不适合您的用例,那么首先将它们放在字典中是很愚蠢的。

在任何其他用例中,您所做的是声明三个xmlObjects 的常规、惯用的 Objective C 方式。如果你真的想知道是否有办法绕过它,当然有,但大多数都很傻。

更好的解决方案可能是切换语言。Python、Ruby、Applescript、ObjC++、eero 等都让您可以像访问 ObjC 一样轻松访问 ObjC 运行时,并且拥有更简洁的惯用方式做事。例如,在 Python 中:

system_domain = xmlObject.alloc()
system_description = xmlObject.alloc()
system_type = xmlObject.alloc()

甚至:

system_domain, system_description, system_type = [xmlObject.alloc() for _ in range(3)]

如果你必须连续初始化 500 个这样的东西,另一个合理的选择是编写一些简单的代码来生成你的 ObjC 代码。

但如果你真的想留在 ObjC 中,这里有一些愚蠢的解决方案:

您可以xmlObject通过执行以下操作将出现次数从 6 次减少到 4 次:

xmlObject *system_domain = [xmlObject alloc],
     *system_description = [xmlObject alloc],
            *system_type = [xmlObject alloc];

或到 3:

id system_domain = [xmlObject alloc];
id system_description = [xmlObject alloc];
id system_type = [xmlObject alloc];

或为 1:

Class x = xmlObject;
id system_domain = [x alloc];
id system_description = [x alloc];
id system_type = [x alloc];

或者:

id makeXmlObject() { return [xmlObject alloc]; }
...

id system_domain = makeXmlObject();
id system_description = makeXmlObject();
id system_type = makeXmlObject();

一些旁注:

您可能不想使用[xmlObject alloc]. 这是一个足够的内存块来构造一个xmlObject, 连接到xmlObject类,但在其他方面完全未初始化。你必须调用一个初始化器——通常是-[init],但通常是这样的-[initWithValue: andOtherValue:]——在你可以用它做任何有用的事情之前。

因此,大多数惯用的 ObjC 代码都会充满这样的调用:

Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] initWithFoo:foo];

此外,除非您使用 ARC(或 GC),否则您通常希望autorelease在对象初始化后立即使用它;否则,您必须手动管理内存(这很难做到正确,因为要快 10 倍)。所以,如果你不得不处理非 ARC 代码,你会看到:

Bar *bar = [[[Bar alloc] initWithFoo:foo] autorelease];

幸运的是,许多类都提供了类构造函数,它们可以合二为一:

NSString *s = [NSString stringWithUTF8String:c]; // ARC or no ARC

当它们存在时,您应该使用这些便利方法,但要习惯alloc] init];(并且alloc] init] autorelease];,如果您必须处理 pre-ARC/pre-GC 代码)惯用语,因为您将需要它。

在所有其他具有 ObjC 运行时绑定的语言中也是如此;例如,在 Python 中,您Bar.barWithFoo(foo)尽可能地这样做,Bar.alloc().initWithFoo_(foo)否则。

同时,你不能这样的原因:

xmlObject *system_domain, *system_description, *system_type = [xmlObject alloc];

……或者……</p>

system_domain = system_description = system_type = [xmlObject alloc];

……唯一合理的解释是将所有三个对象设置为xmlObject. 如果您只调用alloc一次,则只会分配一件事。

最后,使用小写首字母命名 ObjC 类被认为是不好的风格。它应该是XMLObject(或者也许XmlObject,但 Apple 喜欢明确缩写词和首字母缩写词),而不是xmlObject. 而且,除了非常简单的项目,大多数人喜欢给他们的所有类一个 2 或 3 个字母的前缀(如 Apple 的 NS),以便区分来自不同子项目、第三方库等的类。 ,所以“ALIXMLObject”可能会更好。

于 2012-10-02T18:45:50.367 回答
0

您必须执行以下操作:

xmlObject *system_domain = [xmlObject alloc],
     *system_description = [xmlObject alloc],
            *system_type = [xmlObject alloc];

这几乎不比你的第一个版本好。

于 2012-10-02T17:49:02.083 回答