7

Note: My question is not related to this.

Besides the variable not being seen outside the file it is declared in, in terms of memory allocation, is there any difference between declaring this (outside of a method):

NSString *const kMyConstant = @"Hello World";

Or this:

static NSString *const kMyConstant = @"Hello World";
Community
  • 1
  • 1
Rui Peres
  • 25,741
  • 9
  • 87
  • 137

4 Answers4

2

In terms of memory allocation, no, there's no difference. Both variables are pointers to the same string constant, both are allocated once, and in both cases, their lifetime is the lifetime of the program.

  • Both are allocated @ compile time, would there be a difference for non-objects vars? – Rui Peres Sep 03 '13 at 09:29
  • @JackyBoy In what sense? –  Sep 03 '13 at 09:40
  • int's float's structures – Rui Peres Sep 03 '13 at 09:59
  • @JackyBoy I know what non-object types are. But I feel you are confusing the allocation of a pointer with the allocation of the memory ot points to. We can declare any primitive as a static lobal variable, it will be allocated and alive until the program exits. If it's a pointer, as in the case of Objective-C objects, you can assign a pointer to some other memory to it - but the lifetime of that memory is not at all related to the lifetime of the pointer. –  Sep 03 '13 at 10:36
  • So the memory of the pointer can de destroyed, but the memory it's pointing to, will be kept? – Rui Peres Sep 03 '13 at 10:39
  • @JackyBoy Of course! They're different things, not tied to each other. That's why `void *p = malloc(100); p = NULL;` leaks memory, for example. –  Sep 03 '13 at 10:59
  • I have one question. If we use #define macro for string value to use as constant. If there is any benefit in terms of memory allocation as static const have life time same as program? – Nitesh Borad Jan 05 '17 at 13:57
1

No, there is not, it simply effects the visibility of the object outside the compilation unit.

This can also be achieved using:

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

EDIT That is cobblers; the visibility hidden attribute affects visibility outside of a shared object, not the compilation unit.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Because the thing is, without the "static" wouldn't the NSString be deallocated once the (for example if it was declared inside a UIViewController) VC would be destroyed? – Rui Peres Sep 03 '13 at 09:38
  • @JackyBoy No. The fact that it's a constant string means `retain` and `release`, etc have no effect at all. If it was a normal string I wouldn't expect it to be deallocated either, regardless of `static`, given I don't believe ARC would be able to follow the lifetime of the object. Might be wrong about that, but I would expect you, the developer, to have to assign `nil` to release it. – trojanfoe Sep 03 '13 at 09:40
  • It's true for static, they stay as long the program is "alive". But without the static, in what basis is that true? (ref: http://ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.6.html) – Rui Peres Sep 03 '13 at 10:01
  • @JackyBoy I must admit, I didn't read it all, but the statement "The storage class, static, similarly provides a lifetime over the entire program, however; it provides a way to limit the scope of such variables" seems to agree with the answers here. – trojanfoe Sep 03 '13 at 10:03
  • Yes but without the "static" would it be different? Would it stay for the lifetime of the entire program? Or release upon the release of the object which uses it. – Rui Peres Sep 03 '13 at 10:05
  • @JackyBoy As mentioned, it's the same. They are both "global". – trojanfoe Sep 03 '13 at 10:05
1

I think this is a very interesting question, since it shows some clear and understandable management of constants on one hand and some obvious exceptions that Objective C and clang include when handling NSString class constants.

I believe the following does apply:

Above declarations and initializations from the question make no difference to memory management. It simple doesn't really exist. Constants are simply included in bundle and are not allocated in classic terms. Meaning that value from object class is pointing to bundle memory location where string constant is. You can easily find this out when comparing address of such NSString and its object class. String address is very low, pointing to the bundle location addresses range. You can see that addresses of other strings that were initialized in the code point to a very different locations. Objective C runtime doesn't perform any kind of memory management on string constants, since it would be quite awkward to "release" or delete something from bundle. So, if you play with this in non-ARC environment, you will see that retain and release are simply ignored.

To end this by answering the question: no, there isn't any difference managing memory in both cases. It's simply not done. Memory is allocated by bundle and it is released by OS when application ends. It doesn't apply only for declarations and assigning explicit constant outside the implementation, but also inside any method.

mbpro
  • 2,460
  • 3
  • 22
  • 37
0

It does make a difference with the above two expressions, when you declare variable with static scope, it retains their assigned values over repeated calls which is good for performance reason in some cases however there is a downside of it as memory for static variable is allocated once and stay there through out the program until the application finishes. Besides it is quite difficult to release statically defined variables. It will never release the memory until application finishes and you will run the risk of using a whole ton of memory and ARC can't help you here.

ldindu
  • 4,270
  • 2
  • 20
  • 24