Generic Class / Protocol for UIView / CALayer - Software Development Issues

I have a very simple question regarding some software development solutions using the iOS SDK.

Suppose I have a class that controls the presentation of view objects in my application ( UIManager ). This class allows external controller classes to add view objects to it. Presentation objects can be of two types: subclasses CALayer and UIView .

My question is which interface is more suitable for such a UIManager class. For instance:

 @interface UIManager : UIView {} // 1) - (void)addGenericViewObject:(id)genericViewObject; // 2) - (void)addUIViewObject:(UIView*)uiViewObject; - (void)addCALayerObject:(CALayer*)caLayerObject; // 3) - (void)addMyProtocolTypeViewObject(id<MyProtocolType>)myProtocolTypeViewObject; @end 

1) Is the id type too general?

2) Can having a different method signature for each type lead to terrible code duplication?

3) Is there a way to present the UIView and CALayer via <MyProtocolType> ?

Or, more commonly, having a class that handles these different objects interchangeably is not good?

The implementation of UIManager will be something like this:

 @implementation UIManager // 1) - (void)addGenericViewObject:(id)genericViewObject { if ([genericViewObject isKindOfClass:[UIView class]]) { [_uiViewsContainer addSubview:(UIView*)genericViewObject]; } else if ([genericViewObject isKindOfClass:[CALayer class]]) { [_caLayersContainer addSublayer:(CALayer*)genericViewObject]; } } @end 

Type checking is always bad, perhaps if <MyProtocolType> solves the situation, how can I represent both the UIView class and CALayer in the protocol? Both classes simply correspond to <NSObject> .

Thank you in advance

+4
source share
1 answer

Type checking is a must. I think we can reformulate the question: "I want the manager to take UIView or CALayer and do different things with them, but reject all other things." In this case, enter a chest check, and I wholeheartedly recommend that you just check the type and throw an exception if everything goes wrong as expected.

You can add a private category that is really, really personal, for example, with a 64-character random identifier, for both CALayer and UIView, which matches the classes for the user protocol and just checks for compliance. But it does what type checks, and is a very large (unnecessary) job; The last time I tried, GCC seems to hate this.

I think this might work if you later deal with a lot of classes:

 - (BOOL) addInterfaceObject:(id)anObject { void (^handler)(); if (!(handler = [self interfaceObjectHandlerForClass:[anObject class]])) return NO; // Or throw an exception handler(anObject); return YES; } - (void(^)(id anObject)) interfaceObjectHandlerForClass:(Class)aClass { // Or retrieve copy-autoreleased blocks from a dictionary if ([aClass isSubclassOfClass:[UIView class]]) return ^ (id anObject) { [self.view addSubview:(UIView *)anObject]; }; if ([aClass isSubclassOfClass:[CALayer class]]) return ^ (id anObject) { [self.view.layer addSublayer:(CALayer *)anObject]; }; return nil; } 
+1
source

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


All Articles