Xcode - 在 AppDelegate 中加载声音时出现 Apple Mach-O 链接器错误
Posted
技术标签:
【中文标题】Xcode - 在 AppDelegate 中加载声音时出现 Apple Mach-O 链接器错误【英文标题】:Xcode - Apple Mach-O Linker errors when loading sound in AppDelegate 【发布时间】:2015-02-08 23:37:49 【问题描述】:我目前的应用设置如下:
我在 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 没有显示任何警告或错误:
构建失败:Apple Mach-O 链接器错误
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 编程的新手,我花了几个小时试图自己解决这个问题,但我就是做不到。请帮忙。
【问题讨论】:
您的意思是在TitleScreen.h
中有一个@interface
吗?
【参考方案1】:
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
【讨论】:
感谢您的快速回复。 Mach-O 错误消失了,但现在我在 TitleScreen.h 的AudioServicePlaySystemSound(tapSoundID);
行上得到了一个 Use of undeclared identifier 'tapSoundID'
。
哦,我现在明白了,我认为我必须从 .h 文件中删除 extern SystemSoundID tapSoundID;
时遇到错误。我将它添加回 .h 并在 .m 文件中定义了它,一切都按照我现在想要的方式工作!非常感谢您的帮助和链接~【参考方案2】:
你误解了如何使用全局变量。
你声明了一个没有 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
注意项目现在如何包含tapSoundID
的两个定义?这就是“重复符号”链接器错误的原因。如果你想让一个全局变量在整个程序中都可以访问,你需要保留
extern SystemSoundID tapSoundID;
在AppDelegate.h
中,但您还必须在AppDelegate.m
中声明全局变量(不带extern
):
SystemSoundID tapSoundID;
@implementation AppDelegate
//...
extern
关键字告诉链接器全局变量是在另一个文件中定义的。当您仅使用extern
声明变量时,链接器会查找实际定义,但找不到它,从而导致“未定义符号”错误。使用AppDelegate.h
中的extern
定义和AppDelegate.m
中的全局变量,链接器可以看到AppDelegate.m
中的变量,并使其可供包括AppDelegate.h
的所有文件访问。 p>
【讨论】:
感谢您的解释。 Yuchen 在上面的回答中提到了它,但我花了一分钟才意识到我需要两者。您的帖子进一步澄清了这一点。以上是关于Xcode - 在 AppDelegate 中加载声音时出现 Apple Mach-O 链接器错误的主要内容,如果未能解决你的问题,请参考以下文章
无法在 AppDelegate 应用程序方法的数组中加载 HTTP POST 响应数据。如何解决这个问题?
需要从 appdelegate 加载 UIViewController 并在 Storyboard App 中加载时隐藏 UITabBarController