How can I optimize this huge if / else if-block within watchValueForKey

I have a controller that is registered as an observer for LOT properties on views. This is our method -observeValueForKeyPath:::::

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void*)context
{

   if( context == kStrokeColorWellChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStrokeColorProperty];
   }
   else if( context == kFillColorWellChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFillColorProperty];
   }
   else if( context == kBodyStyleNumChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kBodyStyleNumProperty];
   }
   else if( context == kStyleChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStyleProperty];
   }
   else if( context == kStepStyleChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStepStyleProperty];
   }
   else if( context == kFirstHeadStyleChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFirstHeadStyleProperty];
   }
   else if( context == kSecondHeadStyleChangedContext )
   {
      [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kSecondHeadStyleProperty];
   }

And actually about 3 of these operators else if.
One thing you can see is that every block has the same code, which makes me think that it is possible to optimize it.

My initial thought was to have NSDictionary, called keyPathForContextDictionary, where the keys are constants with a suffix Context(of type void*), and the values ​​are the corresponding string constants indicated by the Propertysuffix symbol

Then this method will need only one line:

[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:keyPathForContextDictionary[context]];

, , , keyPath, . , , , (, color). , ,

, void* NSDictionary. ... - , ?

EDIT: , :

void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
void * const kFillColorWellChangedContext = (void*)&kFillColorWellChangedContext;
void * const kBodyStyleNumChangedContext = (void*)&kBodyStyleNumChangedContext;
void * const kStyleChangedContext = (void*)&kStyleChangedContext;

NSString *const kStrokeColorProperty     = @"strokeColor";
NSString *const kFillColorProperty       = @"fillColor";
NSString *const kShadowProperty          = @"shadow";
NSString *const kBodyStyleNumProperty    = @"bodyStyleNum";
NSString *const kStyleProperty           = @"style";
+4
2

, NSStrings*

, void* NSValues w/-valueWithPointer. , void*

:

   NSString *toolKeyPath = [[ToolController keyPathFromContextDictionary] objectForKey:[NSValue valueWithPointer:context]];

   if( toolKeyPath )
   {
      if( [change objectForKey:NSKeyValueChangeNewKey] == (id)[NSNull null] )
      {
         [self setValue:nil forKey:toolKeyPath];
      }
      else
      {
         [self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:toolKeyPath];
      }
   }

:

+(NSDictionary*) keyPathFromContextDictionary
{
   return @{
             [NSValue valueWithPointer:kStrokeColorWellChangedContext] : kStrokeColorProperty,
             [NSValue valueWithPointer:kFillColorWellChangedContext] : kFillColorProperty,
             [NSValue valueWithPointer:kBodyStyleNumChangedContext] : kBodyStyleNumProperty,
             [NSValue valueWithPointer:kStyleChangedContext] : kStyleProperty,
             [NSValue valueWithPointer:kStepStyleChangedContext] : kStepStyleProperty,
             [NSValue valueWithPointer:kFirstHeadStyleChangedContext] : kFirstHeadStyleProperty,
             [NSValue valueWithPointer:kSecondHeadStyleChangedContext] : kSecondHeadStyleProperty,
             [NSValue valueWithPointer:kShadowChangedContext] : kShadowProperty,
             [NSValue valueWithPointer:kStrokeWidthChangedContext] : kStrokeWidthProperty,
             [NSValue valueWithPointer:kBlurRadiusChangedContext] : kBlurRadiusProperty,
             [NSValue valueWithPointer:kFontSizeChangedContext] : kFontSizeProperty
         };
}
+1

void * , , " ". context , , , . , , .

, kTHINGYChangedContext NSString , , .

:

NSString * const kStrokeColorWellChangedContext = @"StrokeColorWellChangedContext";

, :

[colorWell addObserver:self
            forKeyPath:keyPath
               options:options
               context:(__bridge void *)kStrokeColorWellChangedContext];

, , :

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void*)ctx
{
    NSString * context = (__bridge NSString *)ctx;
    // Use context, not ctx, from here on.
}

.

+1

Source: https://habr.com/ru/post/1611678/


All Articles