> Am 24.02.2020 um 08:38 schrieb mickb...@posteo.net:
>
> On 17.11.2019 16:53, Richard Frith-Macdonald wrote:
>>> On 17 Nov 2019, at 15:08, Riccardo Mottola <riccardo.mott...@libero.it>
>>> wrote:
>>> I wanted to subclass NSMutableArray, so that I can easily add some extra
>>> methods.
>>> I declared my subclass like this:
>>> @interface FileArray : NSMutableArray
>>> {}
>>> However, when I run my app, I get this:
>>> StepSync.app/StepSync: Uncaught exception NSInvalidArgumentException,
>>> reason: [FileArray-addObject:] should be overridden by subclass
>>> I did override all concrete methods in the easiest possible way, calling
>>> super. For addObject I did:
>>> - (void)addObject:(id)anObject
>>> {
>>> [super addObject:anObject];
>>> }
>>> why is this not enough or not working in any case?
>> Because NSMutable array is an abstract class. You need to create a
>> concrete class with actual instance variables to store data in.
>> What you could have done to get the effect you seem to want is have a
>> concrete instance do the work for you:
>> @interface FileArray : NSMutableArray
>> {
>> NSMutableArray *content;
>> }
>> @end
>> @implementation FileArray
>> - (void) addObject: (id)anObject
>> {
>> [content addObject: anObject];
>> }
>> - (void) dealloc
>> {
>> [content release];
>> [super dealloc];
>> }
>> - (id) initWithCapacity: (NSUInteger)capacity
>> {
>> content = [[NSMutableArray alloc] initWithCapacity: capacity];
>> return self;
>> }
>> etc.
>> In this case the line
>> content = [[NSMutableArray alloc] initWithCapacity: capacity];
>> will actually create a GSMutableArray instance (a concrete subclass)
>> that your class implementation can use to store the objects.
>
> No, I do not understand. If NSMutableArray is an abstract class, how can I
> make the following call?
>
> [content addObject: anObject];
>
> And if the call
>
> content = [[NSMutableArray alloc] initWithCapacity: capacity];
>
> creates a GSMutableArray instance, why an hypothetical subclass shouldn't do
> the same?
>
> myMutableArray = [[MyMutableArray alloc] initWithCapacity: capacity];
>
> The solution you proposed is surely an option. Bu If there is a class I can
> directly use (instantate an object), it should be possible to subclass it,
> just adding any new method, but keeping access to those of the superclass as
> they are, without the need of wrapping each.
>
> Thanks for being patient with me: I am an expert C++ programmer, but with
> very few experience in Obj-C, even for a number of doubts like that one above.
The trick here is that the alloc method in the NSMutableArray class has a
special case to allocate a GSMutableArray instance when called on the
NSMutableArray class, but not so for any subclass. So [NSMutableArray alloc]
returns a GSMutableArray instance, while [MyMutableArray alloc] returns a
MyMutableArray instance.
Wolfgang