Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring extern NSString causes linker error

This is ridiculous, im trying to create a sound bool to turn of in app sounds. I keep getting

Undefined symbols for architecture i386:
"_kPlaySoundPrefsKey", referenced from:
  -[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have checked that all my files are linked in build phases, I have deleted the appdelegate .m where im getting the error before I even get to call the bool in any of my view controllers, and re imported it in build phases. Checked I have relevant framweworks in place. I have even checked a previous app I made with same code and the code it appears to be exactly the same with no error (built with previous version of xcode). Taking it right back to basics I get the error as soon as I add the following code to my App Delegate,

.h

#import <UIKit/UIKit.h>
extern NSString *kPlaySoundPrefsKey;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

.m

#import "AppDelegate.h"
#import <AudioToolbox/AudioToolbox.h> 

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions
 {

NSDictionary *defaultDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
 forKey:kPlaySoundPrefsKey];

return YES;
}

If I change extern NSString *kPlaySoundPrefsKey; to NSString *kPlaySoundPrefsKey; it builds then crashes...Im out of ideas now

like image 758
JSA986 Avatar asked Aug 29 '12 21:08

JSA986


1 Answers

When you declaring something as extern you are telling the compiler the type AND that you will define it somewhere else. In your case you never define your variable.

So in your .h you would have:

extern NSString* kPlaySoundPrefsKey;

But in some .m you must also have

NSString* kPlaySoundPrefsKey = @"play_sounds"; // or some value

Since in your case these are constants you can also specify:

extern NSString* const kPlaySoundPrefsKey;

and

NSString* const kPlaySoundPrefsKey = @"play_sounds"; 

The addition of the const qualifier will cause a compiler error if someone ever writes something like

kPlaySoundPrefsKey = @"some_other_value";
like image 88
idz Avatar answered Oct 21 '22 14:10

idz