How to extend NSArray?

Here is my attempt:

H file:

@interface Strings : NSArray @end 

M file:

 @implementation Strings - (id) init { [self initWithObjects: @"One.", nil]; return self; } @end 

When I run, I get the following:

'NSInvalidArgumentException', reason: '* - [NSArray initWithObjects: count:]: a method defined only for an abstract class. Define - [lines of initWithObjects: count:]! ''

Here is what I did instead:

H file:

 @interface Strings : NSObject + (NSArray*) getStrings; @end 

M file:

 @implementation Strings + (NSArray*) getStrings { NSArray* strings = [[NSArray alloc] initWithObjects: @"One.", nil]; return strings; } @end 
+6
source share
5 answers

NSArray - a cluster of classes (link to Apple documentation) . This means that when you try to create an NSArray system creates some private subclass of NSArray . The NSArray class defines an interface; subclasses of NSArray provide an interface implementation.

You can write your own subclass of NSArray , but you must provide your own storage for the objects in the array. You must initialize this repository yourself. The error message reports this, saying that you need to override initWithObjects:count: in your subclass. Your redefinition should put objects in any repository that you allocate as part of the implementation of your class.

The implementation of the variational method initWithObjects: NSArray is just a wrapper around initWithObjects:count: so you do not need to implement initWithObjects:

+8
source

Getting NSArray is something you should avoid. From the documentation:

Remember that NSArray is the public interface of the class cluster and that this entails your subclass. Primitive NSArray methods do not include any designated initializers. This means that you must provide the repository for your subclass and implement the primitive methods that directly act on this repository.

This means that when you initialize the array, you do not get an instance of NSArray . You will get an instance of a completely different class that just has the same interface. That's why the subclassification doesn't work the way you think it works: you have to fully implement the repository yourself. This is why the documentation further says:

Any subclass of NSArray must override the primitive instance methods count and objectAtIndex :. These methods should work in the backup storage that you provide for collection items. In this repository, you can use a static array, a standard NSArray object, or some other type or data mechanism. You can also override, in part or in full, any other NSArray method for which you want to provide an alternative implementation.

And last but not least, in any case, you would have had the wrong initialization. You would need to call super :

 - (id)init { self = [super initWithObjects:@"One", @"Two", nil]; if (!self) return nil; return self; } 

But, as I just said, it's just not that easy. You will get the same exception again. Therefore, you should simply avoid executing NSArray .

What you can do is add a category to add methods to all instances of NSArray .

+5
source

NSArray does not support subclasses in this way. You can add a category though, although this is not recommended universally.

See Objective C - subclass NSArray for more thoughts.

+2
source

perhaps,

 self = [super initWithObjects:...]; 
+1
source

You need to assign self and call the init method for the superclass.

 if (self = [super initWithObjects:...]) { ... } return self; 
+1
source

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


All Articles