28

In trying to de-couple my model from the view controllers that display fetched data, when an asynchronous fetch completes, I post an NSNotification.

 [[NSNotificationCenter defaultCenter] postNotificationName:@"foobarFetchSuccess" object: foo];

I've gotten into the habit of using:

 #define FOO_FETCH_SUCCESS  @"foobarFetchSuccess"

in a common header file and then using it for the addObserver: and removeObserver: as well as the postNotificationName:

 [[NSNotificationCenter defaultCenter] addObserver:self @selector(gotData)
                                              name:FOO_FETCH_SUCCESS object: baz];

So @"foobarFetchSuccess" string is used all over the place. And there are many more just like him. So what's the best way to declare a string once and use it everywhere?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Rayfleck
  • 12,116
  • 8
  • 48
  • 74

2 Answers2

56

As for using constant strings in your project, there’s another question on Stack Overflow about that: Constants in Objective C.

As for naming notifications, Coding Guidelines for Cocoa suggests the following:

Notifications are identified by global NSString objects whose names are composed in this way:

[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification

Community
  • 1
  • 1
  • For the sake of completion, what about the naming convention for the observing selector? According to the [guideline](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF), it's almost the same as the Notification name, minus "Notification" and the class namespace prefix. eq: **windowDidLoad** Is this accurate? – pixelfreak Jun 18 '11 at 01:00
  • @pix You can name them at your will. However, if it’s a delegate method that is called because of a notification, then what you’ve said applies — a delegate wouldn’t register for the notification; instead, it’d automatically receive the corresponding message with the notification parameter. Note that `-windowDidLoad` is not really related to a notification (it doesn’t receive an `NSNotification` argument), but the naming convention is similar indeed. –  Jun 18 '11 at 01:06
  • My gripe with the convention is that names become really long and overall readability is negatively impacted. – rtcarlson Jan 06 '16 at 15:08
3

This doesn't follow the Apple-suggested format exactly, nor does it directly answer your question, but I thought I'd share these handy-dandy text macros that I use to spare myself a little typing when making notification and key names. You can assign these a keyboard shortcut, type in and select the [Did|Will] + [UniquePartOfName] segment, then hit the shortcut to produce the variable and its value. You could also use $(FILENAMEASIDENTIFIER) instead of $(PROJECTNAME) if you were defining these strings in the header of a particular class, and that would conform to the suggestion.

//MARK: Notification strings
    { /*
       * Use the selection to make the name and string for a Notification.
       * The string has a prefix placeholder, defaulting to the project name.
       */
      Identifier = objc.notestring;
      BasedOn = objc;
      IsMenuItem = YES;
      Name = "Notification Name From Selection";
      TextString = "<#$(PROJECTNAME)#><#!notename!#>Notification = @\"<#$(PROJECTNAME)#><#!notename!#>Notification\";";
      CompletionPrefix = notestring;
    },
    { /*
       * Insert placeholders to make the name and string for a Notification.
       * This is for use without a selection, and so "only" activates at the 
       * beginning of the line.
       */
      Identifier = objc.notestring.bol;
      BasedOn = objc.notestring;
      IsMenuItem = YES;
      Name = "Notification Name From Selection";
      OnlyAtBOL = YES;
      CompletionPrefix = notestring;
    },

//MARK: Default Key strings
    { /*
       * Convert the selection into a name and string for use in the User 
       * Defaults system. The string has a placeholder for a prefix, which
       * defaults to the project name.
       */
      Identifier = objc.defaultskeystring;
      BasedOn = objc;
      IsMenuItem = YES;
      Name = "UserDefaults Key From Selection";
      OnlyAtBOL = NO;
      TextString = "<#$(PROJECTNAME)#><#!keyname!#>Key = @\"<#$(PROJECTNAME)#><#!keyname!#>Key\";";
      CompletionPrefix = defaultskey;
    },
    { /*
       * Insert placeholders to make the name and string for a a key for the
       * User Defaults system. This is for use without a selection, and so 
       * "only" activates at the beginning of the line.
       */
      Identifier = objc.defaultskeystring.bol;
      BasedOn = objc.defaultskeystring;
      IsMenuItem = YES;
      OnlyAtBOL = YES;
      Name = "UserDefaults Key From Selection";
      CompletionPrefix = defaultskey;
    },

These are Xcode 3 macros. I know the macro system is different in Xcode 4 (which I'm not using yet), but I believe the conversion is simple and can be automated.

jscs
  • 63,694
  • 13
  • 151
  • 195