2015-05-11 2 views
5

Я создал библиотеку предопределенных цветов для использования в Swift и Objective-C, и я переписал подключаемый модуль для Xcode, который просматривает цвет в редакторе, чтобы он работал с моей библиотекой (наряду с несколькими другими изменениями).Динамический вызов метода в Swift

В настоящее время плагин имеет список созданных цветов. Я не в восторге от этого решения, потому что это означает, что в любое время, когда я меняю список цветов, мне тоже нужно изменить свой код. Кроме того, мне не нравится, когда структура данных висит вокруг около 1500 цветов и строк. Кажется, это не так эффективно или элегантно.

Что я хотел бы сделать, а не хранить все цвета в памяти, это вызвать правильную функцию NSColor, когда она встречает имя функции в коде. Я обнаружил, что могу проверить, отвечает ли NSColor на селектор с функцией responsesToSelector: но вызов функции performSelector: не соответствует моим потребностям, так как мне нужно возвращаемое значение из вызова.

Итак, есть ли способ пойти от этого.

let colourDict [ String : NSColor ] = [ 
    "blackColor" : NSColor.blackColor(), 
    "whiteColor" : NSColor.whiteColor() ] 
... 

let foundColour = colourDict[ colourMethodName ] 

Что-то вроде этого.

if (NColor.respondsToSelector (Selector (colourMethodName)) { 
    foundColour = NSColor.performSelector (Selector (colourMethodName)) 
} 

Очевидно, что это не было бы performSelector: сама функция, но я ищу для этого типа функциональности, за исключением того, что будет возвращаться обратно объект NSColor.

Спасибо.

+0

Я думаю, что вы должны быть в состоянии [присвоить функцию переменного, и назвать его, когда вам нужно вернуть значение] (http://stackoverflow.com/a/24521823/1445366), чтобы выполнить то, что вы хотите. (Это делает этот вопрос дубликатом [Alternative to performSelector in Swift?] (Http://stackoverflow.com/questions/24158427/alternative-to-performselector-in-swift)) –

+1

Похоже, вы пытаетесь дублировать функциональность ['NSColorList'] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSColorList_Class/index.html # // apple_ref/occ/cl/NSColorList) class ... – rickster

+1

У вас может быть массив методов, но, честно говоря, t держат 1500 цветов. – Schemetrical

ответ

0

Поскольку вы определяете свое собственное именованное цветовое пространство, вам нужно что-то сделать самостоятельно, потому что NSColor не поддерживает много предопределенных цветов. Я могу подумать о двух вариантах:

Вы можете создать крошечную базу данных, которая содержит цвета и загружать ее в качестве ресурса в проект. Найдите значения RGBA по имени и затем создайте цвет по этому определению.

Расширение NSColor с функцией, которая включает имя для возврата цвета. Тогда вы не держите их в памяти. (Мой пример использует UIColor, но NSColor будет работать тоже)

extension UIColor { 
    class func colorByName(name:String) -> UIColor { 
     switch name.lowercaseString { 
      case "blackcolor": 
       return UIColor.blackColor() 
      case "whitecolor": 
       return UIColor.whiteColor() 
      case "redcolor": 
       return UIColor.redColor() 
      // etc 
     default: 
      return UIColor.clearColor() 
     } 
    } 
} 


let color = UIColor.colorByName("redcolor") 

Конечно, если вы действительно умны вы можете объединить два и сделать это так, определение цвета может быть обновлено во время выполнения.

+0

Я создал библиотеки и размещал их на GitHub, которые являются расширениями UIColor и NSColor, которые определяют около 1500 дополнительных цветов, чтобы вы могли писать код, такой как 'UIColor.africanVioletColor()'. Этот плагин должен показать вам небольшую коробку в Xcode, что на самом деле этот цвет (наряду с другими способами создания цветов). Я просто стараюсь избегать наличия большой структуры данных и кода для ее создания. – CanadianMacFan

+0

@CanadianMacFan Что такое URL? –

+0

Библиотека называется [Радуга UIColor Extension] (https://github.com/NorthernRealities/Rainbow). Я скоро получаю версию для NSColor. Если вы заинтересованы в плагине, который позволяет просматривать и изменять цвета в Xcode, вы можете найти его здесь (https://github.com/NorthernRealities/ColorSenseRainbow). – CanadianMacFan

0

Я не понимаю, что случилось с первоначальным предложением Аарона Брагера. Начните со словарем функций:

let colourDict : [ String :() -> UIColor ] = [ 
    "blackColor" : UIColor.blackColor, 
    "whiteColor" : UIColor.whiteColor, 
    // ... and so on ... 
] 

Это чрезвычайно эффективным - гораздо более эффективным, чем создание всех цветов в память и держать их там - потому что это просто список указателей, в основном.

Чтобы получить фактический цвет, получит функцию цвета по имени, и называют его:

let actualColor = colourDict["blackColor"]!() 
+0

Спасибо за пример и дальнейшие объяснения. И если я не найду что-то лучше, я пойду с этим. Проблема в том, что у меня есть около 1500 элементов для определения, так как моя библиотека добавляет много новых цветов в качестве расширения. Плюс каждый раз, когда я вношу изменения в свою библиотеку, это становится еще одним местом, которое я должен помнить, чтобы сделать это изменение тоже. Вот почему я надеялся найти решение, похожее на performSelector. Не то, чтобы performSelector работал бы, потому что он ничего не возвращает, и мне нужен возвращаемый объект NSColor. – CanadianMacFan

+0

Конечно, я понимаю. Если вы действительно хотите преобразовать метод преобразования строки в метод, придерживайтесь Objective-C и делайте с ним. Я просто иллюстрировал подход. – matt

Смежные вопросы