2014-03-04 2 views
3

Я создаю категорию UIColor, где у меня есть набор цветов, к которым я хочу легко получить доступ, а затем кешировать.Макрос препроцессора комплекса

Это в основном, как я создаю свои цвета:

#define RGB(r, g, b) [self colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1] 

// [..] 

+ (instancetype)pigletColor 
{ 
    static UIColor *pigletColor = nil; 
    if (!pigletColor) { 
     pigletColor = RGB(237.0, 0.0, 130.0); 
    } 
    return pigletColor; 
} 

Однако, повторяя выше десять раз не очень аккуратно и сухо, поэтому я пытаюсь создать макрос позволяет мне сделать это легко.

В идеале, я бы хотел заменить вышеприведенный COLORGETTER(piglet, 234.0, 0.0, 130.0). Я пошла на это, но я не могу заставить его работать. Это, насколько я получил:

#define COLORGETTER(name, red, green, blue)\ 
+ (instancetype *)##name##Color\ 
{\ 
    static UIColor *##name##Color = nil;\ 
    if (!##name##Color) {\ 
     ##name##Color = RGB(red, green, blue);\ 
    }\ 
    return ##name##Color;\ 
} 

Однако выше не работает, так как я не могу выяснить #/## операторов.

Любые идеи?

ответ

3

Есть две ошибки:

  • (instancetype *) должен быть (instancetype). Подобно id, это уже указатель.
  • ##name##Color должно быть name##Color. Вы хотите связать имя и «Цвет» с одним токеном, но не с предыдущим токеном.

Так что это, кажется, работает:

#define COLORGETTER(name, red, green, blue)\ 
    + (instancetype) name##Color\ 
    {\ 
     static UIColor * name##Color = nil;\ 
     if (!name##Color)\ 
     {\ 
      name##Color = RGB(red, green, blue);\ 
     }\ 
     return name##Color;\ 
    } 
+0

Nice один! Моя фиксация после этого состояла из 37 дополнений и 223 делеций. Благодаря! Если бы 24 цветовых геттера я мог упростить. :) – Alex

3

Несколько вещей

  1. instancetype уже указатель, не используйте instancetype *.
  2. ##между идентификаторы - name ## Color, а не ## name ## Color.
  3. Вы должны действительно использовать блок dispatch_once вместо if.
  4. Необязательно, но вам не нужно настраивать имя для местных жителей. Легче просто использовать одно имя.
#define COLORGETTER(name, red, green, blue)\ 
+ (UIColor *)name##Color\ 
{\ 
    static UIColor *color = nil;\ 
    static dispatch_once_t onceToken;\ 
    dispatch_once(&onceToken, ^{\ 
     color = RGB(red, green, blue);\ 
    });\ 
    return color;\  
} 
Смежные вопросы