NSMutableString *newPath = [NSMutableString stringWithCapacity:42];
或者
NSMutableString *newPath = [[NSMutableString alloc] init];
有什么特别的原因为什么我应该使用其中一个,从表面上看,使用第一个似乎更容易?
是的。除非您有特定的理由不这样做,否则请始终立即自动释放。
第一个原因是很容易忘记写release
信息。如果您在创建对象的同一语句中自动释放该对象(如在 中[[[… alloc] init] autorelease]
),那么忘记它会困难得多,而且当您这样做时会更加明显。便利的工厂方法(如stringWithCapacity:
)为您自动释放对象,因此就像您自己自动释放它一样,您不必担心以后释放它。
其次,即使您确实记得写单独的release
消息,也很容易不点击它。两种方式是提前返回:
NSString *str = [[NSString alloc] initWithString:@"foo"];
BOOL success = [str writeToFile:path atomically:NO];
if (!success)
return;
[str release];
并抛出或传播异常:
NSString *str = [[NSString alloc] initWithString:@"foo"];
//Throws NSRangeException if str is not in the array or is only in the array as the last object
NSString *otherStr = [myArray objectAtIndex:[myArray indexOfObject:str] + 1];
[str release];
“不这样做的具体原因”通常是您有一个创建大量对象的紧密循环,在这种情况下,您可能希望手动管理循环中尽可能多的对象,以保持您的对象数量向下。然而,只有当你有证据证明这是你的问题时才这样做(无论是来自 Shark 的硬数字,来自 Instruments 的硬数字,或者只要循环运行足够长的时间,你的系统就会进入分页地狱)。
其他可能更好的解决方案包括将循环分成两个嵌套循环(外部循环为内部循环创建和排出自动释放池)并切换到 NSOperation。(但是,请确保您对队列一次运行的操作数设置了限制——否则,您可能更容易陷入分页地狱。)
第一个更好,因为它给编译器一种大小感?
它更好,但不是因为这个原因。
对于编译器来说,这只是另一个类消息。编译器不知道也不关心它做了什么;它所知道和关心的stringWithCapacity:
就是向用户播放歌曲的消息。
它确实给了NSMutableString一个大小提示——该类将知道它最初可能想要分配多少字符存储空间。您从中获得的任何好处都可能很小(至少在 Mac 上),但是如果您手边有这些信息,为什么不使用它呢?相反,我不会特意去计算它。
我看到很多声明写在两行(即)
NSMutableString *newPath;
newPath = [NSMutableString stringWithCapacity:42];
我个人更喜欢单线,这只是个人风格的另一个例子吗?
是的。但是,使变量未初始化存在一定的风险。如果您决定养成这样的习惯,请务必打开“运行静态分析器”构建设置。