【问题标题】:Use of Static in Objective-c在 Objective-c 中使用静态
【发布时间】:2013-09-03 08:40:46
【问题描述】:

注意:我的问题与this 无关。

除了在声明它的文件之外看不到变量之外,在内存分配方面,声明 this(在方法之外)有什么区别:

NSString *const kMyConstant = @"Hello World";

或者这个:

static NSString *const kMyConstant = @"Hello World";

【问题讨论】:

    标签: objective-c c static static-variables


    【解决方案1】:

    在内存分配方面,不,没有区别。两个变量都是指向同一个字符串常量的指针,都被分配一次,在这两种情况下,它们的生命周期就是程序的生命周期。

    【讨论】:

    • 两者都是@编译时分配的,非对象变量会有区别吗?
    • @JackyBoy 在什么意义上?
    • int 的浮点结构
    • @JackyBoy 我知道非对象类型是什么。但是我觉得您将指针的分配与指向的内存分配混淆了。我们可以将任何原语声明为静态 lobal 变量,它将被分配并处于活动状态,直到程序退出。如果它是一个指针,就像在 Objective-C 对象的情况下,你可以为它分配一个指向其他内存的指针 - 但该内存的生命周期与指针的生命周期根本无关。
    • 所以指针的内存可以销毁,但它指向的内存会保留吗?
    【解决方案2】:

    不,没有,它只是影响编译单元外对象的可见性

    这也可以通过以下方式实现:

    __attribute__ ((visibility ("hidden")) NSString *const kMyConstant = @"Hello World";
    

    EDIT 那是补鞋匠; visibility hidden 属性影响共享对象外部的可见性,而不是编译单元。

    【讨论】:

    • 因为事情是,如果没有“静态”,一旦(例如,如果它在 UIViewController 中声明)VC 将被销毁,NSString 不会被释放吗?
    • @JackyBoy 不。它是一个常量字符串这一事实意味着retainrelease 等根本没有效果。如果它是一个普通的字符串,我也不希望它被释放,不管static,因为我不相信 ARC 能够遵循对象的生命周期。这可能是错误的,但我希望你,开发者,必须分配nil 来发布它。
    • 静态是真的,只要程序“活着”,它们就会一直存在。但如果没有静态,那有什么依据呢? (参考:ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.6.html
    • @JackyBoy 我必须承认,我没有阅读全部内容,但是声明“静态存储类同样为整个程序提供了生命周期;它提供了一种方法来限制这些变量的范围”似乎与这里的答案一致。
    • 是的,但没有“静态”会有所不同吗?它会在整个程序的生命周期内一直存在吗?或者在释放使用它的对象时释放。
    【解决方案3】:

    我认为这是一个非常有趣的问题,因为它一方面展示了对常量的一些清晰易懂的管理,而且在处理 NSString 类常量时,Objective C 和 clang 包含了一些明显的异常。

    我相信以下内容确实适用:

    问题中的上述声明和初始化对内存管理没有影响。简单的并不存在。常量只是简单地包含在包中,而不是按照经典术语分配。这意味着来自对象类的值指向字符串常量所在的捆绑内存位置。在比较此类 NSString 及其对象类的地址时,您可以很容易地发现这一点。字符串地址很低,指向捆绑位置地址范围。您可以看到在代码中初始化的其他字符串的地址指向一个非常不同的位置。 Objective C 运行时不对字符串常量执行任何类型的内存管理,因为从 bundle 中“释放”或删除某些东西会很尴尬。因此,如果您在非 ARC 环境中使用它,您会看到简单地忽略了保留和释放。

    通过回答以下问题来结束这一点:不,在这两种情况下管理内存没有任何区别。它根本没有完成。内存由捆绑包分配,并在应用程序结束时由操作系统释放。它不仅适用于实现之外的声明和分配显式常量,也适用于任何方法内部。

    【讨论】:

      【解决方案4】:

      它确实与上述两个表达式有所不同,当您声明具有静态范围的变量时,它会在重复调用时保留它们的分配值,这在某些情况下出于性能原因是好的,但是它作为静态内存有一个缺点变量被分配一次并在整个程序中一直存在,直到应用程序完成。此外,释放静态定义的变量非常困难。在应用程序完成之前,它永远不会释放内存,您将冒着使用大量内存的风险,而 ARC 在这里帮不了您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        • 2012-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 2012-07-05
        相关资源
        最近更新 更多