我怎么知道 Xcode Objective-C 中出现错误的地方?
How I can know where raises the error in Xcode Objective-C?
我是 Objective-C 的初学者,我正在为 运行 在 iOS 7.1 中的这段代码而苦苦挣扎,但在 iOS 8.
我如何从堆栈跟踪中知道问题出在哪里?
以及为什么代码在旧版本 (iOS 7) 中有效而在新版本中无效?
使用不正确的 NSMutableDictionary
或 NSArray
有问题吗?
- (NSDictionary*) MPNowPlayingInfoCenterNowPlayingInfo {
NSMutableDictionary *info;
if (self.currentPlayable && self.currentPlayable.mediaItemProperties) {
info = self.currentPlayable.mediaItemProperties.mutableCopy;
} else {
info = [NSMutableDictionary dictionaryWithCapacity:10];
}
// Set defaults if missing
NSArray* metadata = self.player.currentItem.asset.commonMetadata;
if (!info[MPMediaItemPropertyPlaybackDuration]) {
float _playbackDuration = self.currentPlayerItem ? CMTimeGetSeconds(self.currentPlayerItem.duration) : 0.0f;
NSNumber* playbackDuration = @(_playbackDuration);
info[MPMediaItemPropertyPlaybackDuration] = playbackDuration;
}
if (!info[MPNowPlayingInfoPropertyElapsedPlaybackTime]) {
float _elapsedPlaybackTime = self.currentPlayerItem ? CMTimeGetSeconds(self.currentPlayerItem.currentTime) : 0.0f;
NSNumber* elapsedPlaybackTime = @(_elapsedPlaybackTime);
info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsedPlaybackTime;
}
if (!info[MPMediaItemPropertyArtwork]) {
NSArray* artworkMetadata = [AVMetadataItem metadataItemsFromArray:metadata
withKey:AVMetadataCommonKeyArtwork
keySpace:AVMetadataKeySpaceCommon];
if (artworkMetadata.count > 0) {
AVMetadataItem* artworkMetadataItem = artworkMetadata[0];
UIImage* artworkImage = [UIImage imageWithData:artworkMetadataItem.value[@"data"]];
MPMediaItemArtwork* artwork = [[MPMediaItemArtwork alloc] initWithImage:artworkImage];
info[MPMediaItemPropertyArtwork] = artwork;
}
}
if (!info[MPMediaItemPropertyTitle]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyTitle] = _metadataItem.value;
}
}
if (!info[MPMediaItemPropertyAlbumTitle]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyAlbumName keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyAlbumTitle] = _metadataItem.value;
}
}
if (!info[MPMediaItemPropertyArtist]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyArtist] = _metadataItem.value;
}
}
return info;
}
这里是堆栈跟踪:
HelloCordova[20791:74393] THREAD WARNING: ['AudioPlayerPlugin'] took '248.958008' ms. Plugin should use a background thread.
2015-04-01 10:16:21.377 HelloCordova[20791:74903] Retrieving lock screen art...
2015-04-01 10:16:29.295 HelloCordova[20791:74903] Initializing lock screen art...
2015-04-01 10:16:29.296 HelloCordova[20791:74903] Creating MPMediaItemArtwork...
2015-04-01 10:16:29.322 HelloCordova[20791:74903] Done retrieving lock screen art.
2015-04-01 10:16:51.439 HelloCordova[20791:74393] -[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7ffb33e0fe80
Apr 1 10:16:51 Pourias-Mac.local rtcreporting[20791] <Info>: logging starts...
Apr 1 10:16:51 Pourias-Mac.local rtcreporting[20791] <Debug>: setMessageLoggingBlock: called
2015-04-01 10:16:51.618 HelloCordova[20791:74393] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7ffb33e0fe80'
*** First throw call stack:
(
0 CoreFoundation 0x000000010241ea75 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000104f96bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000102425d1d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010237d9dc ___forwarding___ + 988
4 CoreFoundation 0x000000010237d578 _CF_forwarding_prep_0 + 120
5 HelloCordova 0x00000001021ce2a8 -[PRXPlayer MPNowPlayingInfoCenterNowPlayingInfo] + 2056
6 HelloCordova 0x00000001021d4549 -[NYPRPlayer MPNowPlayingInfoCenterNowPlayingInfo] + 57
7 HelloCordova 0x00000001021ce9e5 -[PRXPlayer setMPNowPlayingInfoCenterNowPlayingInfo] + 85
8 HelloCordova 0x00000001021d5acb -[NYPRPlayer refreshMetadata] + 43
9 HelloCordova 0x00000001021c4e02 -[AudioStreamHandler updateProgress] + 146
10 HelloCordova 0x00000001021c576b -[AudioStreamHandler observedPlayerDidObservePeriodicTimeInterval:] + 91
11 HelloCordova 0x00000001021cc85e -[PRXPlayer reportPlayerTimeIntervalToObservers] + 670
12 HelloCordova 0x00000001021caa4b -[PRXPlayer playerItemDidJumpTime:] + 91
13 CoreFoundation 0x00000001023ee7fc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
14 CoreFoundation 0x00000001022ee204 _CFXNotificationPost + 2484
15 AVFoundation 0x0000000103b4c0b2 __avplayeritem_fpItemNotificationCallback_block_invoke + 7447
16 libdispatch.dylib 0x00000001056b8186 _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x00000001056d7614 _dispatch_client_callout + 8
18 libdispatch.dylib 0x00000001056bfa1c _dispatch_main_queue_callback_4CF + 1664
19 CoreFoundation 0x0000000102386749 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
20 CoreFoundation 0x000000010234962b __CFRunLoopRun + 2043
21 CoreFoundation 0x0000000102348bc6 CFRunLoopRunSpecific + 470
22 GraphicsServices 0x0000000106735a58 GSEventRunModal + 161
23 UIKit 0x000000010280e580 UIApplicationMain + 1282
24 HelloCordova 0x000000010219a0e7 main + 71
25 libdyld.dylib 0x000000010570c145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
这个问题的一部分与 This question 重复,但作为新手 iOS 开发人员,我什至不知道从哪里开始问我的问题,很抱歉重复的问题,但在其他问题中,我得到了自己的答案并检查了它是否是正确答案。
假设您正在使用 Xcode,您可以打开异常断点。这将导致应用程序在抛出异常时跳转到中断的行。
问题是您正在尝试为不是字典而是 NSData
的内容获取 objectForKey
。我这是这一行:
UIImage* artworkImage = [UIImage imageWithData:artworkMetadataItem.value[@"data"]];
也许你可以在那里添加断点并打印出来artworkMetadataItem.value
看看它是什么类型。
如果这不是问题所在,您可以尝试 运行 通过您的代码逐步查看导致崩溃的语句。
希望这能奏效!让我知道进展如何
我是 Objective-C 的初学者,我正在为 运行 在 iOS 7.1 中的这段代码而苦苦挣扎,但在 iOS 8.
我如何从堆栈跟踪中知道问题出在哪里?
以及为什么代码在旧版本 (iOS 7) 中有效而在新版本中无效?
使用不正确的 NSMutableDictionary
或 NSArray
有问题吗?
- (NSDictionary*) MPNowPlayingInfoCenterNowPlayingInfo {
NSMutableDictionary *info;
if (self.currentPlayable && self.currentPlayable.mediaItemProperties) {
info = self.currentPlayable.mediaItemProperties.mutableCopy;
} else {
info = [NSMutableDictionary dictionaryWithCapacity:10];
}
// Set defaults if missing
NSArray* metadata = self.player.currentItem.asset.commonMetadata;
if (!info[MPMediaItemPropertyPlaybackDuration]) {
float _playbackDuration = self.currentPlayerItem ? CMTimeGetSeconds(self.currentPlayerItem.duration) : 0.0f;
NSNumber* playbackDuration = @(_playbackDuration);
info[MPMediaItemPropertyPlaybackDuration] = playbackDuration;
}
if (!info[MPNowPlayingInfoPropertyElapsedPlaybackTime]) {
float _elapsedPlaybackTime = self.currentPlayerItem ? CMTimeGetSeconds(self.currentPlayerItem.currentTime) : 0.0f;
NSNumber* elapsedPlaybackTime = @(_elapsedPlaybackTime);
info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsedPlaybackTime;
}
if (!info[MPMediaItemPropertyArtwork]) {
NSArray* artworkMetadata = [AVMetadataItem metadataItemsFromArray:metadata
withKey:AVMetadataCommonKeyArtwork
keySpace:AVMetadataKeySpaceCommon];
if (artworkMetadata.count > 0) {
AVMetadataItem* artworkMetadataItem = artworkMetadata[0];
UIImage* artworkImage = [UIImage imageWithData:artworkMetadataItem.value[@"data"]];
MPMediaItemArtwork* artwork = [[MPMediaItemArtwork alloc] initWithImage:artworkImage];
info[MPMediaItemPropertyArtwork] = artwork;
}
}
if (!info[MPMediaItemPropertyTitle]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyTitle] = _metadataItem.value;
}
}
if (!info[MPMediaItemPropertyAlbumTitle]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyAlbumName keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyAlbumTitle] = _metadataItem.value;
}
}
if (!info[MPMediaItemPropertyArtist]) {
NSArray* _metadata = [AVMetadataItem metadataItemsFromArray:metadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon];
if (_metadata.count > 0) {
AVMetadataItem* _metadataItem = _metadata[0];
info[MPMediaItemPropertyArtist] = _metadataItem.value;
}
}
return info;
}
这里是堆栈跟踪:
HelloCordova[20791:74393] THREAD WARNING: ['AudioPlayerPlugin'] took '248.958008' ms. Plugin should use a background thread.
2015-04-01 10:16:21.377 HelloCordova[20791:74903] Retrieving lock screen art...
2015-04-01 10:16:29.295 HelloCordova[20791:74903] Initializing lock screen art...
2015-04-01 10:16:29.296 HelloCordova[20791:74903] Creating MPMediaItemArtwork...
2015-04-01 10:16:29.322 HelloCordova[20791:74903] Done retrieving lock screen art.
2015-04-01 10:16:51.439 HelloCordova[20791:74393] -[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7ffb33e0fe80
Apr 1 10:16:51 Pourias-Mac.local rtcreporting[20791] <Info>: logging starts...
Apr 1 10:16:51 Pourias-Mac.local rtcreporting[20791] <Debug>: setMessageLoggingBlock: called
2015-04-01 10:16:51.618 HelloCordova[20791:74393] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7ffb33e0fe80'
*** First throw call stack:
(
0 CoreFoundation 0x000000010241ea75 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000104f96bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000102425d1d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010237d9dc ___forwarding___ + 988
4 CoreFoundation 0x000000010237d578 _CF_forwarding_prep_0 + 120
5 HelloCordova 0x00000001021ce2a8 -[PRXPlayer MPNowPlayingInfoCenterNowPlayingInfo] + 2056
6 HelloCordova 0x00000001021d4549 -[NYPRPlayer MPNowPlayingInfoCenterNowPlayingInfo] + 57
7 HelloCordova 0x00000001021ce9e5 -[PRXPlayer setMPNowPlayingInfoCenterNowPlayingInfo] + 85
8 HelloCordova 0x00000001021d5acb -[NYPRPlayer refreshMetadata] + 43
9 HelloCordova 0x00000001021c4e02 -[AudioStreamHandler updateProgress] + 146
10 HelloCordova 0x00000001021c576b -[AudioStreamHandler observedPlayerDidObservePeriodicTimeInterval:] + 91
11 HelloCordova 0x00000001021cc85e -[PRXPlayer reportPlayerTimeIntervalToObservers] + 670
12 HelloCordova 0x00000001021caa4b -[PRXPlayer playerItemDidJumpTime:] + 91
13 CoreFoundation 0x00000001023ee7fc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
14 CoreFoundation 0x00000001022ee204 _CFXNotificationPost + 2484
15 AVFoundation 0x0000000103b4c0b2 __avplayeritem_fpItemNotificationCallback_block_invoke + 7447
16 libdispatch.dylib 0x00000001056b8186 _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x00000001056d7614 _dispatch_client_callout + 8
18 libdispatch.dylib 0x00000001056bfa1c _dispatch_main_queue_callback_4CF + 1664
19 CoreFoundation 0x0000000102386749 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
20 CoreFoundation 0x000000010234962b __CFRunLoopRun + 2043
21 CoreFoundation 0x0000000102348bc6 CFRunLoopRunSpecific + 470
22 GraphicsServices 0x0000000106735a58 GSEventRunModal + 161
23 UIKit 0x000000010280e580 UIApplicationMain + 1282
24 HelloCordova 0x000000010219a0e7 main + 71
25 libdyld.dylib 0x000000010570c145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
这个问题的一部分与 This question 重复,但作为新手 iOS 开发人员,我什至不知道从哪里开始问我的问题,很抱歉重复的问题,但在其他问题中,我得到了自己的答案并检查了它是否是正确答案。
假设您正在使用 Xcode,您可以打开异常断点。这将导致应用程序在抛出异常时跳转到中断的行。
问题是您正在尝试为不是字典而是 NSData
的内容获取 objectForKey
。我这是这一行:
UIImage* artworkImage = [UIImage imageWithData:artworkMetadataItem.value[@"data"]];
也许你可以在那里添加断点并打印出来artworkMetadataItem.value
看看它是什么类型。
如果这不是问题所在,您可以尝试 运行 通过您的代码逐步查看导致崩溃的语句。
希望这能奏效!让我知道进展如何