4

I keep reading different things about this and it seems dangerously confusing. Can someone please tell me the proper pattern to define notification strings that can be used globally? Everything I've tried have caused linker errors. For example, in my GlobalVariables singleton I added:

#import <Foundation/Foundation.h>
extern NSString *kMPTimeChanged;

@interface GlobalVariables : NSObject etc. 

And then in the init:

@implementation GlobalVariables

#pragma mark Singleton Methods

+ (id)sharedGlobals {
    static GlobalVariables *sharedGlobals = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedGlobals = [[self alloc] init];

    });
    return sharedGlobals;
}

- (id)init {
    if (self = [super init]) {

      kMPTimeChanged=@"kMPTimeChanged";

    return self;
}

It didn't build, I got multiple errors.

JoshDG
  • 3,871
  • 10
  • 51
  • 85
  • possible duplicate of [Constants in Objective C](http://stackoverflow.com/questions/538996/constants-in-objective-c) – Wain Nov 01 '13 at 15:49

4 Answers4

18

In your .h file you should write:

extern NSString * const kMPTimeChanged;

In your .m file, you should write:

NSString * const kMPTimeChanged = @"My Constant";

Both of these of these should be outside of your @interface and @implementation blocks.

Holly
  • 5,270
  • 1
  • 24
  • 27
  • I'll add that with this simple solution there is no need for the class (unless it servers other purposes). Just have these two lines and that is it. – rmaddy Nov 01 '13 at 15:51
4

I'd recommend declaring your variables as const extern. Then:

// Globals.h
extern NSString * const kMPTimeChanged;

// Globals.m
NSString * const kMPTimeChanged = @"...";
Kevin Sylvestre
  • 37,288
  • 33
  • 152
  • 232
  • See [this post](http://stackoverflow.com/questions/10091825/constant-pointer-vs-pointer-on-a-constant-value) about the difference between `const NSString *` and `NSString const *`. An object of type `NSString` is already immutable, so there is no need to use `const` as you did. – Holly Nov 01 '13 at 15:57
  • @Neal Yup. Typo. I fixed. – Kevin Sylvestre Nov 01 '13 at 18:44
1

If your values are constants, just use a header, for example called Constants.h. In this header you can declare constants like this:

#define kMPTimeChanged @"kMPTimeChanged"
Linuxios
  • 34,849
  • 13
  • 91
  • 116
  • #define is nice and easy and I admit I use it time and again, but usually I want my data type. – DBD Nov 01 '13 at 19:10
  • @DBD: What do you mean "want my datatype"? – Linuxios Nov 01 '13 at 19:11
  • The const is type-safe, but the #define replace happens before compilation (basically like a search and replace) so you could change a @"fubar" to 37. It would most likely cause problems later, but you wouldn't know. If you tried to do that with a const it would warn you before you could even finish typing it. – DBD Nov 01 '13 at 19:38
  • This is working for me,it's easy way declare constant :) @Linuxios – Jaywant Khedkar Oct 29 '15 at 10:44
0

I don't like the extern variables. Sometimes it's hard to figure out where they came from and I wind up having to do searches on large code bases for poorly named variables which just seem to exist from no where. I guess I'm sort of in the global variables are evil crowd. Still, they are useful, so I have my own solution.

My solution is simple Constants class with a bunch of static methods, properties, whatever is needed (all read only of course). The problem is you are stuck importing this class in everywhere! There is an easy solution to that though.

In the import in your project-Prefix.pch file. This will automatically get added to all your code and you'll be able use your constants and still know where they are coming from without having to think about it.

Here is an example of my project-Prefix.pch file

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>

    #import "Constants.h"
#endif

Now you access Constants.serverUrl anywhere and still know exactly where serverUrl came from.

DBD
  • 23,075
  • 12
  • 60
  • 84