2

我正在尝试使用关联对象(一个 NSMutableDictionary 和一个 NSNumber)在 iTunesTrack 上编写一个类别

#import "iTunes.h"
#import <objc/runtime.h>

@interface iTunesTrack (dictionary)
- (NSMutableDictionary*) getDictionary;
- (NSNumber*) getScan;
- (BOOL)scanTrack:(NSString *)equationString;
@end

这失败了:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_iTunesTrack", referenced from:
      l_OBJC_$_CATEGORY_iTunesTrack_$_dictionary in iTunesTrack+dictionary.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我已经仔细检查了是否添加了 Scripting Bridge 框架以及是否已将 iTunesTrack+dictionary.m 文件附加到目标。将类别与脚本桥结合起来可能会出现一些错误吗?


更新:

如果我用 SBObject 替换 iTunesTrack,这可行。不过,我不知道为什么。


更新 2:

这个问题是可以重现的:

  1. 创建新项目
  2. 添加 Scripting Bridge Framework 和 iTunes.h 头文件。
  3. 使用任意名称创建新类别的 iTunesTrack
  4. 确保iTunesTrack+name.h进口iTunes.h
  5. 建造

我发现这个页面描述了使用 NSProxy 和 NSCache 来存储 iTunesTrack 对象。这会比尝试创建一个类别更好吗?

4

4 回答 4

1

您不能在 iTunesTrack(或 ITunesTrack,或任何它在您的标题中调用的)上放置一个类别,因为这要求该类在链接时存在,但它不存在:Scripting Bridge 在运行时动态创建目标应用程序的类。(而且它们在技术上具有任意名称,这就是-classForScriptingClass存在的原因。)向生成的类添加方法仍然是可能的,但这意味着与运行时混在一起,这通常比它的价值更麻烦。只需打开您的类别方法SBObject并尽量小心。

于 2014-12-04T00:00:49.067 回答
1

脚本桥是一团糟。

该类iTunesTrack实际上是ITunesTrack在后台调用的。
我认为它们与主要的小写字母不太一致i

这就是为什么他们在一段时间后改变了它,但可能不想在头文件中这样做,而不是改变他们的 API。

我不认为有办法解决这个问题。

但是,您可以只在 上创建类别SBObject

// The interface can be declared as iTunesTrack
@interface iTunesTrack (Additions)
...
@end

// The category MUST be implemented on SBObject
@implementation SBObject (Additions)
...
@end

警告

请注意,每个 类别都可用SBObject,因此请确保所有属性和方法都具有唯一的接口。

于 2013-11-28T10:22:53.770 回答
0

NSAddict 的回答指出了我一直想做的事情的方法:为 SBObject 类型实现 debugQuickLookObject 以使调试更容易。这是执行 iTunesTrack 和 iTunesArtwork 的类别。

//  SBObject+Extensions.h

@import ScriptingBridge;

@interface SBObject (Extensions)

- (id)debugQuickLookObject;

@end


//  SBObject+Extensions.m

#import "iTunes.h"

@implementation SBObject (Extensions)

- (id)debugQuickLookObject
{
    NSString *className = self.className;

    if ([className isEqualToString:@"ITunesTrack"])
    {
        return [self handleITunesTrack];
    }
    else if ([className isEqualToString:@"ITunesArtwork"])
    {
        return [self handleITunesArtwork];
    }

    return [self description];
}

- (NSString*)handleITunesTrack
{
    iTunesTrack *track = (iTunesTrack *)self;

    NSMutableString *s = [NSMutableString new];

    [s appendFormat:@"Title:    %@\n", track.name];
    [s appendFormat:@"Artist:   %@\n", track.artist];
    [s appendFormat:@"Album:    %@\n", track.album];
    [s appendFormat:@"Duration: %f seconds\n", track.duration];

    return s;
}

- (NSImage*)handleITunesArtwork
{
    iTunesArtwork *artwork = (iTunesArtwork *)self;

    NSData *data   = [artwork rawData];
    NSImage *image = [[NSImage alloc] initWithData:data];

    return image;
}

@end
于 2016-03-19T03:18:51.363 回答
-2

您可能会在此讨论中找到答案: 链接器命令失败,退出代码为 1(使用 -v 来查看调用)

您也可以尝试清理然后重新构建您的项目或转到项目 -> 构建设置 -> 有效架构并检查是否全部正确。其中一些建议可能会对您有所帮助。

于 2013-05-06T15:01:48.033 回答