gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issues subclassing NSMutableArray


From: Wolfgang Lux
Subject: Re: Issues subclassing NSMutableArray
Date: Mon, 24 Feb 2020 11:53:07 +0100


> Am 24.02.2020 um 08:38 schrieb address@hidden:
> 
> On 17.11.2019 16:53, Richard Frith-Macdonald wrote:
>>> On 17 Nov 2019, at 15:08, Riccardo Mottola <address@hidden> 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

[Prev in Thread] Current Thread [Next in Thread]