Связывание проблем с категорией в Scripting Bridge

Я пытаюсь написать категорию поверх iTunesTrack со связанными объектами (NSMutableDictionary и NSNumber)

#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?


Обновлять:

Если я заменю iTunesTrack на SBObject, это сработает. Я понятия не имею, почему, хотя.


Обновление 2:

Эта проблема воспроизводима:

  1. Создать новый проект
  2. Добавьте Scripting Bridge Framework и заголовочный файл iTunes.h.
  3. Создайте новую категорию iTunesTrack с произвольным именем
  4. Убедитесь, что iTunesTrack+name.h импортирует iTunes.h
  5. Строить

Я нашел эту страницу, на которой описывается использование NSProxy и NSCache для хранения объектов iTunesTrack. Будет ли это лучшим решением, чем пытаться создать категорию?


person abroekhof    schedule 06.05.2013    source источник


Ответы (4)


Scripting Bridge — это полный беспорядок.

Класс 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, поэтому убедитесь, что все свойства и методы имеют уникальный интерфейс.

person IluTov    schedule 28.11.2013
comment
Ответ NSAddict указал способ сделать то, что я всегда хотел: реализовать - (id)debugQuickLookObject; для классов SBObject. - person Ron Reuter; 19.03.2016

Вы не можете поместить категорию в iTunesTrack (или ITunesTrack, или как там она называется в вашем заголовке), потому что для этого требуется, чтобы класс существовал во время компоновки, а это не так: Scripting Bridge динамически создает классы целевого приложения во время выполнения. (И у них технически произвольные имена, поэтому -classForScriptingClass и существует.) Добавить метод к сгенерированному классу по-прежнему можно, но это означает возиться со средой выполнения, что обычно приносит больше проблем, чем пользы. Просто поместите свой метод категории на SBObject и постарайтесь быть осторожным.

person Chris N    schedule 04.12.2014

Ответ NSAddict указал способ сделать то, что я всегда хотел: реализовать debugQuickLookObject для типов SBObject, чтобы упростить отладку. Вот категория, которая делает 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
person Ron Reuter    schedule 19.03.2016

Вы можете найти ответ в этом обсуждении: Команда компоновщика завершилась неудачно с кодом выхода 1 (используйте -v, чтобы увидеть вызов)

Также вы можете попробовать очистить, а затем пересобрать свой проект или перейти в Project -> Build Settings -> Valid Architectures и проверить, все ли там правильно. Некоторые из этих советов могут вам помочь.

person Miroslav    schedule 06.05.2013
comment
Я пробовал чистить. Я также только что попытался создать новый проект, добавив только категорию, iTunes.h и Scripting Bridge, и он все еще не работает. - person abroekhof; 06.05.2013