【问题标题】:Setter for NSString, how is it working?NSString 的设置器,它是如何工作的?
【发布时间】:2009-08-28 15:12:22
【问题描述】:

这个问题是上一个问题的后续问题,该问题引发了进一步的问题。我想了解的是这个例子中的指针和对象是什么时候被创建的,以及它们最终会发生什么。我仍在努力解决这个问题,所以请原谅我可能做出的任何错误假设。

// MAIN
int main (int argc, const char * argv[]) {
    PlanetClass *newPlanet_01 = [[PlanetClass alloc] init];
    [newPlanet_01 setGeekName:@"StarWars"];
}

.

// CLASS
@interface PlanetClass : NSObject {
    NSString *geekName;
}

- (NSString*) geekName;
- (void) setGeekName:(NSString*)gName;
@end

.

// SETTER
- (void)setGeekName:(NSString *)gName {
    if (geekName != gName) {
        [geekName release];
        geekName = [gName copy];
    }
}

(A) ... 当第一次创建 PlanetClass "newPlanet_01" 的实例时,是创建了 NSString 实例变量对象,还是只是指向可能的未来对象的指针?如果它只是一个指针,我稍后会在 setter 中释放什么,因为它只是一个指针,而不是指向对象的指针?

(B) ...在上面的例子中,“gName”是一个指向NSString对象@"StarWars"的指针?

(C) ... 接下来是与 gName 不同的指针 geekName(即如果 geekName 尚未指向 @"StarWars")

(D) ... geekName release,代码第一次运行时释放什么,我的理解是geekName只是一个指针,不指向任何东西。还是第一次发布只是不发布任何东西?

(E) ... 最后 geekName = [gName copy];新发布的 geekName 现在被指定为指向 gName 的副本,那么原始 gName 会发生什么?

【问题讨论】:

    标签: objective-c xcode memory nsstring


    【解决方案1】:
    1. 您正在创建一个初始化为nil 的指针。如果您熟悉 C 或 Java,那么 nil 与 NULL 或 null 基本相同——它实际上是一个空指针。
    2. 是的。 @"StarWars" 被称为“字符串文字”。将字符串文字视为程序存储的“永久”字符串,gName(在这种情况下)是指向该字符串内存位置的指针。
    3. 是的——该行确保传入的gName 与对象的geekName 变量不同。假设检查不存在,并且gName 和geekName 指向同一个字符串——然后下一行将释放该字符串,这可能使 next 行无效(它将是复制已发布的字符串——非常糟糕!)。
    4. 假设geekName仍然是nil,那么是的,什么都没有释放;或者更确切地说,release 消息被发送到 nil 对象,它对消息不做任何事情。 (与 C 或 Java 不同,在 Objective-C 中,您可以向 nil 发送消息——但所有此类消息都会被忽略,nil 是所有此类消息的返回值。
    5. 您创建gName 的副本,以防gName 真的是NSMutableString 的一个实例——您不希望其他代码改变您正在处理的字符串不可变的。但是gName 指向的original 对象会发生什么?好吧,这取决于调用者如何处理它。它可以被释放,它可以被保留,它可以被传递给另一个对象......你真的不知道。在这种特殊情况下,由于gName 指向字符串文字“StarWars”,因此该对象不会发生任何事情(因为它是字符串文字——见上文)。而且指针本身只在这个方法的作用域内有效,一旦方法返回就消失了。

    【讨论】:

    • 我有一个关于 5/E 的问题。在这种情况下,这是内存泄漏吗?常量字符串会发生什么?他们的记忆是如何回收的?
    • 非常感谢,完美。关于(5/E),我猜它会在超出范围时被自动销毁(自动),但这只是一个猜测,因为我已经这样做了 8 天 :)
    • 这不是内存泄漏。您不会从字符串常量中回收内存——它们会在程序运行期间一直存在。对于字符串常量,创建它们的代码由编译器发出(因此是可执行二进制文件的一部分)——具体来说,它们存储在称为二进制文件“数据段”的区域中(程序指令存储在在“文本段”中)。因此,您不必担心“释放”或“泄漏”字符串常量的内存。 (至少对于像 ObjC 这样的 C 和 C 派生语言来说是这样。)
    • 阅读内存管理和字符串编程指南(“创建字符串”部分是一个很好的起点)。 developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/…developer.apple.com/documentation/Cocoa/Conceptual/Strings/…
    • 感谢 Benedict,刚开始,我仍然在寻找网络资源的位置,非常感谢您的指点,我将获取 PDF 版本并查看。跨度>
    猜你喜欢
    • 1970-01-01
    • 2010-11-03
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多