声明 extern NSString 会导致链接器错误
Posted
技术标签:
【中文标题】声明 extern NSString 会导致链接器错误【英文标题】:Declaring extern NSString causes linker error 【发布时间】:2012-08-24 13:50:26 【问题描述】:这太荒谬了,我试图创建一个声音布尔来打开应用程序声音。我不断得到
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)
我已经检查了我的所有文件是否都在构建阶段链接,我已经删除了 appdelegate .m,在我什至在我的任何视图控制器中调用 bool 之前我得到了错误,并在构建阶段重新导入它.检查我有相关的框架。我什至检查了我以前使用相同代码制作的应用程序,它的代码似乎完全相同,没有错误(使用以前版本的 xcode 构建)。回到基础,只要将以下代码添加到我的 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;
如果我将 extern NSString *kPlaySoundPrefsKey;
更改为 NSString *kPlaySoundPrefsKey;
它会构建然后崩溃...我现在没有想法了
【问题讨论】:
【参考方案1】:当您将某些内容声明为extern
时,您是在告诉编译器类型并且您将在其他地方定义它。在你的情况下,你永远不会定义你的变量。
所以在你的 .h 中你会有:
extern NSString* kPlaySoundPrefsKey;
但在某些 .m 中你必须也有
NSString* kPlaySoundPrefsKey = @"play_sounds"; // or some value
因为在您的情况下,这些是您也可以指定的常量:
extern NSString* const kPlaySoundPrefsKey;
和
NSString* const kPlaySoundPrefsKey = @"play_sounds";
如果有人写过类似的东西,添加 const 限定符会导致编译器错误
kPlaySoundPrefsKey = @"some_other_value";
【讨论】:
【参考方案2】:即使我正确声明并定义了 extern const string,我也会遇到同样的错误, 问题是,我的常量文件不在编译源列表中。
确保您的 .m 文件出现在构建目标的“编译源”构建阶段。有时,将文件添加到 Xcode 中的项目并不会将所有实现文件添加到适当的目标。
希望这对某些人有所帮助。 参考:linker-error-undefined-symbols-symbols-not-found
【讨论】:
【参考方案3】:首先,确保已定义:
// AppDelegate.h
extern NSString* const kPlaySoundPrefsKey; // << declaration
// AppDelegate.m
NSString * const kPlaySoundPrefsKey = @"kPlaySoundPrefsKey"; // << definition
另见:
"extern const" vs "extern" only
3 questions about extern used in an Objective-C project
Linker error using extern "C" in Objective-C code
【讨论】:
我对原始答案投了反对票,因为它没有解决 OP 问题的根本原因;他从未定义变量。一旦您对其进行了编辑以解决此问题,我将其删除。 @idz 好的。我收到了两个单独的匿名投票(现在都已撤消),其中一个是在提到缺席定义的更新之后。所以,我发现它有点不寻常。谢谢你的解释。 C++ 名称是否会破坏变量?我以为它只对函数起作用。 @JeremyP 在这种情况下(工具链+abi+等),导出的名称是相同的。将删除该部分。干杯。 忍者反对者?哈哈!很长时间@justin,很高兴再次看到你的答案:)【参考方案4】:感谢你们的帮助
我加了
NSString *kPlaySoundPrefsKey = @"playSoundKey";
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultDict];
到应用委托。解决了它
【讨论】:
以上是关于声明 extern NSString 会导致链接器错误的主要内容,如果未能解决你的问题,请参考以下文章