将问题与Scripting Bridge上的类别相关联

时间:2013-05-06 14:49:57

标签: objective-c cocoa objective-c-category scripting-bridge

我正在尝试使用相关对象(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文件已附加到目标。将类别与Scripting Bridge结合起来会出现这种错误吗?


更新

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


更新2:

此问题可重现:

  1. 创建新项目
  2. 添加Scripting Bridge Framework和iTunes.h头文件。
  3. 使用任意名称
  4. 创建新类别的iTunesTrack
  5. 确保iTunesTrack+name.h导入iTunes.h
  6. 构建
  7. 我发现this page描述了使用NSProxy和NSCache存储iTunesTrack对象。这会比尝试制作一个类别更好吗?

4 个答案:

答案 0 :(得分: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上提供,因此请确保所有属性和方法都具有唯一的界面。

答案 1 :(得分:1)

您无法在iTunesTrack(或ITunesTrack或其标题中调用的任何内容)上添加类别,因为这需要在链接时存在类,并且它不会:脚本Bridge在运行时动态创建目标应用程序的类。 (并且它们具有技术上任意的名称,这就是-classForScriptingClass存在的原因。)它仍然可以向生成的类添加方法,但它意味着与运行时相关,这通常比它的价值。只需将您的类别方法放在SBObject上,并尽量小心。

答案 2 :(得分: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

答案 3 :(得分:-2)

您可以在此讨论中找到答案: linker command failed with exit code 1 (use -v to see invocation)

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