的Xcode - 苹果的Mach-O链接错误,在AppDelegate中

问题描述:

加载声音时我现在有我的应用程序的设置是这样的:的Xcode - 苹果的Mach-O链接错误,在AppDelegate中

我设置在AppDelegate.h的extern变量,因为我读过他们作为一个全局变量。还添加了AudioToolbox框架。

AppDelegate.h

#import <UIKit/UIKit.h> 
#import <AudioToolbox/AudioToolbox.h> 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 

extern SystemSoundID tapSoundID; 

@end 

接下来,我将我的代码,因为我要为应用程序的完成开始尽快加载的声音加载在AppDelegate中的didFinishLaunching方法的踢踏声。

AppDelegate.m

#import "AppDelegate.h" 
@interface AppDelegate() 
@end 

@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // Override point for customization after application launch. 

    // Load Tap Sound 
    NSURL *tapSoundPath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tap" ofType:@"mp3"]]; 
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)tapSoundPath, &tapSoundID); 
    return YES; 
} 

@end 

确信导入我的标题画面视图控制器AppDelegate.h类。

TitleScreen.h

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

最后,我使用AudioServicesPlaySystemSound(tapSoundID);当按钮被点击播放声音。

TitleScreen.m

#import "TitleScreen.h" 
@interface TitleScreen() 
@end 

@implementation TitleScreen 

- (IBAction)buttonToGameScreen:(id)sender{ 
    AudioServicesPlaySystemSound(tapSoundID); 
} 

@end 

老实说,我认为这会工作,和Xcode中没有表现出任何警告或错误,直到我试图运行应用程序:

构建失败:苹果Mach-O Linker错误

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

我不知道这些错误是什么意思。我是Objective-C/iOS编程的新手,我花了好几个小时试图自己弄清楚这一点,但我不能。请帮忙。

+0

你的意思是在'TitleScreen.h'中有'@ interface'吗? – NobodyNada 2015-02-08 23:52:32

extern SystemSoundID tapSoundID没有定义tapSoundID。它只是意味着它被定义在别的地方。

让我们把它放在你的AppDelegate.m文件中。

#import "AppDelegate.h" 

SystemSoundID tapSoundID; // Add this 

@interface AppDelegate() 
@end 

而且我认为链接错误将会消失。

你也可以看看这篇文章,它很好地解释了使用extern

3 questions about extern used in an Objective-C project

+0

感谢您的快速回复。 Mach-O错误消失了,但是现在我在TitleScreen.h的'AudioServicePlaySystemSound(tapSoundID)'行中得到'使用未声明的标识符'tapSoundID''。 – user3781632 2015-02-08 23:47:13

+1

哦,我现在看到了,我得到了那个错误,认为我必须从.h文件中删除'extern SystemSoundID tapSoundID;'。我将它添加回.h文件,并在.m文件中进行了定义,一切都按我想要的方式运行!非常感谢帮助和链接〜 – user3781632 2015-02-08 23:54:12

你是误会了如何使用全局变量。

你声明一个全局变量没有extern关键字:

SystemSoundID tapSoundID; 

但是,您将得到“重复的符号”链接错误,如果你简单地定义改变了这一点。这是为什么。

一个#import指令就像复制和粘贴。预处理后,将AppDelegate.m是这样的:

//a few hundred thousand lines of code from UIKit and AudioToolbox here 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 

SystemSoundID tapSoundID; 

@end 


@interface AppDelegate() 
@end 

@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // Override point for customization after application launch. 

    // Load Tap Sound 
    NSURL *tapSoundPath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tap" ofType:@"mp3"]]; 
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)tapSoundPath, &tapSoundID); 
    return YES; 
} 

@end 

TitleScreen.m看起来就像这样:

//a few hundred thousand lines of code from UIKit and AudioToolbox here 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 

SystemSoundID tapSoundID; 

@end 

@interface TitleScreen() 
@end 

@implementation TitleScreen 

- (IBAction)buttonToGameScreen:(id)sender{ 
    AudioServicesPlaySystemSound(tapSoundID); 
} 

@end 

通知该项目现在怎么样包含2点定义为tapSoundID?这是“重复符号”链接器错误的原因。如果你想有一个全局变量是在整个程序的访问,你需要保持

extern SystemSoundID tapSoundID; 
AppDelegate.h

,但你也必须声明全局变量(不extern)在AppDelegate.m

SystemSoundID tapSoundID; 

@implementation AppDelegate 
//... 

extern关键字告诉链接器该全局变量是在另一个文件中定义的。当您仅使用extern声明变量时,链接器查找实际定义,但找不到它,导致“未定义符号”错误。通过AppDelegate.h中的extern定义AppDelegate.m中的全局变量,链接器会看到AppDelegate.m中的变量,并使其可以访问包含AppDelegate.h的所有文件。

+0

感谢您的解释。雨辰在上面的回答中提到了它,但花了我一分钟才意识到我需要两个。你的帖子进一步澄清了。 – user3781632 2015-02-09 00:00:20