extern NSString * const kMyStringOk;
This is a pointer to a constant NSString object, which was already immutable. Defining an unchangeable object to be unchangeable doesn't make much sense, so most likely you were not trying to do it. This pointer can be changed to point elsewhere, which you don't usually want to do. This also generates compiler warning with e.g. isEqualToString.
extern const NSString * kMyStringWarning;
Implementation follows definition. Please note that you can use the const const object, if you really want to:
NSString * const kMyStringOk = @"Ok";
const NSString * kMyStringWarning = @"Warning";
if ([@"Warning" isEqualToString:(NSString *)kMyStringWarning])
// something you don't want to do
kMyStringWarning = @"Don't do it";
else if ([@"Ok" isEqualToString:kMyStringOk])
// something you cannot do
kMyStringOk = @"Warning";
Makes me wonder why to go through all the "protected by const", if you throw it away by using type definition overwriting...