Проблеми при свързване с категория в 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