Inheriting an Objective-C Class Using Factory Methods

I would like to inherit from the framework class, which has a factory method. How can I get the factory method to return an object of my inherited class type? I found this useful article that describes a similar situation, but in their case you have control over the superclass. How can I write, say, a subclass of UIImage that imageNamed: will return an object of my subclass type?

+6
source share
3 answers

I would like to inherit from the framework class, which has a factory method. How can I make the factory method return an object of my inherited class type?

This is all you need to do:

 @interface MONImage : UIImage @end @implementation MONImage @end 

Then:

 MONImage * image = [MONImage imageNamed:name]; 

How can I write, say, a subclass of UIImage that imageNamed: will return an object of my subclass type?

+[UIImage imageNamed:] implementation wrote subclasses from this approach. Therefore, you will need to implement this method yourself.

Here's how to declare a factory method:

 + (instancetype)imageNamed:(NSString *)pName; 

and how to implement it:

 + (instancetype)imageNamed:(NSString *)pName { MONImage * image = [[self alloc] initWithThisDesignatedInitializer:pName]; ^^^^ NOTE: self, not a concrete class ...set up image... return image; } 

but they didn’t do this - +[UIImage imageNamed:] wrote subclasses and returns UIImage when writing MONImage * img = [MONImage imageNamed:pName]; . Sometimes this is done for a good reason. Some methods must have β€œfinal” semantics. This often appears when your method can return several types, as in a class cluster. The language does not express "final" methods, but such a method should be documented at a minimum.


So come to this UIImage case:

 @interface MONImage : UIImage + (instancetype)imageNamed:(NSString *)pName; @end @implementation MONImage + (instancetype)imageNamed:(NSString *)pName { UIImage * source = [UIImage imageNamed:pName]; CGImageRef cgImage = source.CGImage; if (cgImage) return [[self alloc] initWithCGImage:cgImage]; // try it another way return nil; } @end 

Note that UIImage and CGImage are immutable. This should not result in a deep copy of the image data.

+9
source

In your example:

  • Subclass of UIImage , say MyImage
  • Implement the imageNamed: method to do something specific that you need to do.
  • Call this method in this class: MyImage *newImage = [MyImage imageNamed:imageName];
+2
source

The approach that solved my problem was to use the category instead of inheritance (loans are transferred to Jonathan Sichon in the comments on my question). I used associative links to declare and store additional data in a category implementation, as discussed a lot here in SO. I would like to draw attention to the NSObject category implementation proposed by Jonathan, which makes it very simple and elegant to add associative links to any object.

0
source

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


All Articles