我想做这个:
[[ClassA new] addObject:[[ClassA new] addObject:[ClassA new]]];
但编译器返回:
"error: invalid use of void expression"
有没有办法做到这一点?就像在java中一样:
ClassA = new ClassA( new ClassA( new ClassA()));
我想做这个:
[[ClassA new] addObject:[[ClassA new] addObject:[ClassA new]]];
但编译器返回:
"error: invalid use of void expression"
有没有办法做到这一点?就像在java中一样:
ClassA = new ClassA( new ClassA( new ClassA()));
真正的问题是它-[ClassA addObject:]
很可能有一个返回类型 void,所以你不能将该表达式嵌套为外部-addObject
: 调用的参数。例如,请参阅文档-[NSMutableArray addObject:]
- 方法签名是- (void) addObject:(id)anObject
. 如果您习惯于使用另一种语言(尤其是 Java)的不同行为,这可能会让您措手不及。另请注意,-removeObject:
返回void
,而不是被删除的对象。
此外,+new
除非被覆盖,否则每个人都错过了继承的点——请参阅+[NSObject new]
. 然而,使用+new
是“过时的”,并且+alloc/-init...
是首选。一个原因是因为无论如何+new
调用-init
,您必须创建一个 +new... 变体来匹配类中的每个 -init...。到那时,你会得到很多不必要的代码来解决一个非问题。我个人+new
很少使用,只有当我知道我只使用-init
.
由于您来自 Java 背景,如果您对为什么 Objective-C 使用 alloc/init 而不是像 Java、C++ 等这样的新方法感到好奇,请查看这个 SO 问题。
您的代码片段仅new
在 ClassA 上定义的方法是类方法而不是实例方法并且 ClassA 还实现了addObject:
您想要的选择器的情况下才能工作。我不确定您的方法是如何定义的,但要使其正常工作,您需要在 ClassA 上定义以下方法:
+ (ClassA *)new;
- (ClassA *)objectByAddingObject:(ClassA *)newObject;
选择new
器需要返回一个指向新 ClassA 对象的指针,因此它的实现可能包含类似于
return [[ClassA alloc] init];
并且addObject:
选择器需要在另一个 ClassA 中存储一个 ClassA 对象,然后返回带有添加子对象的新对象:
self.object = newObject;
return self;
请注意,由于对 的嵌套调用addObject:
,该方法必须返回 (ClassA *) 而不是 (void),这通常是这种情况。您可能需要考虑重构,以便查看以下内容:
[[ClassA alloc] initWithObject:[[ClassA alloc] initWithObject:[[ClassA alloc] init]]];
问题不在于 new,而在于 addObject,它是一个 void 返回方法。
你的代码:
[[ClassA new] addObject:[[ClassA new] addObject:[ClassA new]]];
将更等同于以下 Java 代码:
ClassA = new ClassA()->AddObject( new ClassA()->AddObject( new ClassA() ) );
出于同样的原因,这将失败,即 AddObject 返回 void,而不是 self。
最重要的是,代码显然会失败,因为 new 是一个“所有权”方法,这意味着您根据内存管理规则获得创建对象的所有权,但是您将它传递给 addObject 然后忘记它,所以没有剩下一个来释放它。此外,您甚至不保存对最终对象的引用。
适当的代码更像是:
ClassA* c2 = [ClassA classA];
[c2 addObject:[ClassA classA]];
ClassA* c = [ClassA classA];
[c addObject:c2];
其中 ClassA 的 classA 方法实现为:
(ClassA*) classA
{
return [[ClassA new] autorelease];
}
或者,您可以添加进一步的方法:
(ClassA*) classAWithObject: (ClassA*) inObject
{
ClassA* c = [ClassA classA];
[c addObject:inObject];
return c;
}
然后写:
ClassA* c = [ClassA classAWithObject:[ClassA classAWithObject:[ClassA classA]]];
这对于 Cocoa/Objective C 的执行方式非常真实,并且等效于您的 Java 代码,并且实际上遵守内存管理规则。
在目标 C 中,通常要创建和初始化一个新对象,您需要执行以下操作:
[[ClassA alloc] init]
alloc,为对象分配内存,并初始化它。
我不知道 ClassA 的详细信息,但我猜你想用以下代码替换你的代码:
[[[ClassA alloc] init] addObject:[[[ClassA alloc] init] addObject:[[ClassA alloc] init]]]
尽管仔细查看您的 java 示例,您似乎正在将新的 ClassA 实例传递给构造函数,但以下可能更等效。(这假设 ClassA 有一个名为 'initWithObject' 的构造函数。)
ClassA *myClass = [[ClassA alloc] initWithObject:[[ClassA alloc] initWithObject:[[ClassA alloc] init]];
编辑:以下不是必需的,因为new
继承自NSObject
. 有关详细信息,请参阅Quinn Taylor 的答案,当您在那里时,请为它的正确性投票。:)
@interface ClassA
{
//...
}
+(ClassA)new;
//...
@end
@implementation ClassA
+(ClassA)new { return [[ClassA alloc] init]; }
//...
@end