6

When i read colleagues' code in my team, i usually found there were two different types of definition for const NSString objects:

static NSString const * and static NSString * const

As far as i know, the former is a pointer point to a const NSString object, and the latter defines a const pointer to a NSString object.

My question is which is a better programming practice and a preferred way when defining a const NSString object in objective-c?

Thx.

Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
dadacomeon
  • 245
  • 3
  • 10
  • As noted below, an NSString is immutable and need not itself be identified as `const`. You presumably want the pointer to be `const`. – Hot Licks May 02 '15 at 12:36
  • (Of course, a literal string is another option.) – Hot Licks May 02 '15 at 12:37
  • what is your goal with the string? it is a value inside a viewcontroller, or an attribute of an entitiy? or you want to define a system wide value, for example a hostaddress, which you want to use in several classes ? or a value that will be set once at runtime but then shall be available througout the app lifecycle? – thorb65 May 02 '15 at 13:29

4 Answers4

12

Generally,

static NSString * const

is a better choice.

Actually, static NSString const * is same to static NSString *, cause the string here is already immutable. If you analyse it deeper, you'll notice that const is absolutely nothing to do with it, NSString is Objective-C's class, it wraps the actual value in C.

Note: NSString is a constant type itself (there's a NSMutableString exists). You only need to define a const pointer for it if u want it to be a constant.


EDIT

static NSString * const var;       // 1
static NSString const * const var; // same to 1, first const is useless
static const NSString * const var; // same to 1, first const is useless

CANNOT do any modification.

static NSString * var;              // 2
static NSString const * var;        // same to 2, the const is useless
static const NSString * var;        // same to 2, the const is useless

CANNOT modify the value of var, but CAN modify the pointer.

static NSMutableString * const var; // 3

CAN modify the value of var, but CANNOT for the pointer.

static NSMutableString * var; // 4

CAN modify both the value & pointer.


EDIT 2

As @user3125367 mentioned,

Immutability in Objective-C terms has nothing to do with constness in C.
...
There are 3 orthogonal things: pointer constness, object field constness and object's high-level mutability.

I agree with him about it. NSString has a higher level (it also inherited form NSObject), const on it should have no effect in fact (not the same meaning about the "no effect on immutable object"). But the complier might take care of it already.

NOTE:

var = @"a";  
var = @"b";  

the code snippet above means the pointer changed, not the value. There's no way to modify the value of NSString instance (for NSMutableString, you can use some methods like -appendString: to modify the value).

If you use

static NSString const * var;

the final var will point to @"b". Instead, if you use

static NSString * const var;

compiler will throw an error, and it's what we want: making the var unchangeable.

Kjuly
  • 34,476
  • 22
  • 104
  • 118
  • Offer a link here might be helpful: http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-and-int-const . :) – Kjuly May 02 '15 at 09:54
  • 1
    I am missing the explanation that one notation means "constant pointer to data" while second is "pointer to constant data". Also there is a difference in usage. You can use "constant pointer" anywhere where "pointer" is expected but you can't use "pointer to constant data" in the same way. – Sulthan May 02 '15 at 11:32
  • 1
    Immutability in Objective-C terms has nothing to do with constness in C. One may write a custom container class that *is* a mutable/immutable cluster, *and* declares a public field that may be mutated unless const MyContainer *x is used. There are 3 orthogonal things: pointer constness, object field constness and object's high-level mutability. NSString just doesn't have any public fields. – user3125367 May 02 '15 at 13:14
  • @user3125367 yes, it makes sense, NSString is a wrap from C, const has nothing to do with it's mutability in fact. – Kjuly May 02 '15 at 13:42
  • @user3125367 i'm thinking that the complier might handles the const for Objective-C classes, just we don't realise it. – Kjuly May 02 '15 at 14:12
  • Not sure what that means. Const is compile-time specifier, it doesn't exist in runtime (except that the compiler is free to put static const data into ro section). Immutability is runtime property indeed. If you're about whether `const X *x; x->f = 0` does generate compile-time error, then I didn't check but pretty sure it does. – user3125367 May 02 '15 at 14:24
0
NSString const *str

means str is immutable.if you change str value for example str=str2, there's error occurs.

NSString *const str

means what str point to is immutable.You can change str = str2;

since NSString is immutable

NSString *const str 

is equal to

NSString *str
leizh007
  • 19
  • 2
-2

I prefer static const NSString *var; because staticand const are qualifiers for the NSString pointer. Only the pointer is const not the NSString.

The NSString will be constant because it is not mutable but a const NSMutableString *s will not make s mutable String become constant and so not modifiable. The pointer to the mutable String s will be constant and the compiler won't allow you to modify it.

Sorry for the inversion: Ken Thomases is right: int * const Var; means the pointer is constant and cannot be changed, but the data it points to can be changed. const int * Var means the data pointed to by Var cannot be changed.

Nicolas Buquet
  • 3,880
  • 28
  • 28
  • can you please explain more clear the case if it is NSMutableString ? – Mejdi Lassidi May 02 '15 at 09:35
  • 1
    Static const NSString * var seems a pointer to a NSString object , not a const pointer. – dadacomeon May 02 '15 at 09:48
  • `static const NSString *var;` as @dadacomeon said, it's a pointer to a const string, and the string here is already immutable, so it's same to `static NSString * var;`. – Kjuly May 02 '15 at 09:56
  • If you declare `static NSString *var`, you can later assign another `NSString *` to var. The compiler will be OK. If you declare `static const NSString *var`, you won't be able to assign another `NSString *`to you var variable: the compiler won't be OK because it is declared `const`. And `static`is just here to specify that this varaible is only accessible inside the file it is declared in. – Nicolas Buquet May 02 '15 at 09:59
  • @dingua If you declare `static const NSMutableString *str`, str is a pointer to a NSMutableString. You can't make it point to another memory address than the initial value. But it point to a NSMutableString type object. You can't make it point to another object, but this object (the NSMutableString) can modify its value because it is 'mutable'. – Nicolas Buquet May 02 '15 at 10:03
  • @NicolasBuquet incorrect, `static const NSMutableString *str` is u can reset the pointer, but cannot modify the value though it's `NSMutableString` type, cause it's a `const NSMutableString`. – Kjuly May 02 '15 at 10:06
  • This answer is wrong. Putting the const before the `*` means that thing which is pointed to is `const`. The pointer is not `const` and can be changed, which is not good for the desired result. – Ken Thomases May 02 '15 at 10:32
  • @dingua Sorry, Ken Thomases is right:`int * const Var;` means the pointer is constant and cannot be changed, but the data it points to can be changed.`const int * Var` means the data pointed to by Var cannot be changed. – Nicolas Buquet May 02 '15 at 11:36
-2

// Demo.h

FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;

// Demo.m

NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";
Vijay yadav
  • 1,220
  • 8
  • 17