> 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


Reply via email to