Welcome to MacForumz.com!
FAQFAQ      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

Trouble extending NSMutableArray

 
   Macintosh computer (Home) -> Programmer Help RSS
Next:  Applescript RSS  
Author Message
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 1) Posted: Mon Oct 29, 2007 11:56 am
Post subject: Trouble extending NSMutableArray
Archived from groups: comp>sys>mac>programmer>help (more info?)

I'm trying to write a category extension of NSMutableArray to load a
file which contains comma delimited lines of text. I have this:

// Initialize newly alloc'd array with a comma separated values file
- (id)initWithContentsOfCSVFile:(NSString *)path
{
if (self = [super init])
{
NSString * file = [path stringByExpandingTildeInPath];
NSString * data = [NSString stringWithContentsOfFile:file];
NSArray * list = [data componentsSeparatedByString:@"\r"];
int i;

for (i=0; i<[list count]; i++)
{
NSString * line = [list objectAtIndex:i];
NSMutableArray * csv = [[NSMutableArray alloc] initWithArray:
[line componentsSeparatedByString:@","]];

// Add the CSV array not the line as text to our array
[self addObject:csv];
[csv release];
}
}
return self;
}

and called like this:

NSMutableArray * array = [[NSMutableArray alloc]
initWithContentsOfCSVFile:@"~/sample.csv"];

but upon entering the method, it immediately get this exception:

<NSInvalidArgumentException> *** -count send to an uninitialized
mutable array object

If I change the caller to do the init first:

NSMutableArray * array = [[[NSMutableArray alloc] init]
initWithContentsOfCSVFile:@"~/sample.csv"];

I don't get this. In the method it says 'self' is a

NSPlaceholderMutableArray

and its super is a

NSMutableArray

so I wasn't sure if the 'init' being called should be [self init] or
[super init] but the immediate exception tells me I'm doing something
wrong, but what?

I had planned to return nil after releasing 'self' is anything was wrong
with the file after some initial checking, but it seems I'm stuck at
square 1. TIA

/los "I was a teenage net-random"

 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Tom Harrington

External


Since: Aug 19, 2003
Posts: 940



(Msg. 2) Posted: Mon Oct 29, 2007 11:56 am
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article ,
slashlos wrote:

> I'm trying to write a category extension of NSMutableArray to load a
> file which contains comma delimited lines of text. I have this:
>
> // Initialize newly alloc'd array with a comma separated values file
> - (id)initWithContentsOfCSVFile:(NSString *)path
> {

Is that the only method you implemented? NSMutableArray's documentation
lists several methods as being required in subclasses.

--
Tom "Tom" Harrington
Independent Mac OS X developer since 2002
http://www.atomicbird.com/

 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
glenn andreas

External


Since: Oct 26, 2007
Posts: 6



(Msg. 3) Posted: Mon Oct 29, 2007 12:01 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article ,
slashlos wrote:

> I'm trying to write a category extension of NSMutableArray to load a
> file which contains comma delimited lines of text. I have this:
>
> // Initialize newly alloc'd array with a comma separated values file
> - (id)initWithContentsOfCSVFile:(NSString *)path
> {
> if (self = [super init])
> {
> NSString * file = [path stringByExpandingTildeInPath];
> NSString * data = [NSString stringWithContentsOfFile:file];
> NSArray * list = [data componentsSeparatedByString:@"\r"];
> int i;
>
> for (i=0; i<[list count]; i++)
> {
> NSString * line = [list objectAtIndex:i];
> NSMutableArray * csv = [[NSMutableArray alloc] initWithArray:
> [line componentsSeparatedByString:@","]];
>
> // Add the CSV array not the line as text to our array
> [self addObject:csv];
> [csv release];
> }
> }
> return self;
> }
>
> and called like this:
>
> NSMutableArray * array = [[NSMutableArray alloc]
> initWithContentsOfCSVFile:@"~/sample.csv"];
>
> but upon entering the method, it immediately get this exception:
>
> <NSInvalidArgumentException> *** -count send to an uninitialized
> mutable array object
>
> If I change the caller to do the init first:
>
> NSMutableArray * array = [[[NSMutableArray alloc] init]
> initWithContentsOfCSVFile:@"~/sample.csv"];
>
> I don't get this.

This is wrong, since you are calling an initializer twice, which you
should never do.

>In the method it says 'self' is a
>
> NSPlaceholderMutableArray
>
> and its super is a
>
> NSMutableArray
>
> so I wasn't sure if the 'init' being called should be [self init] or
> [super init] but the immediate exception tells me I'm doing something
> wrong, but what?
>

The problem is that init is not a designated initializer for an
NSMutableArray (or an NSArray for that matter). You should use
initWithCapacity: instead in your "self = [super init]".

You probably would want something like this:




- (id)initWithContentsOfCSVFile:(NSString *)path
{
NSString * file = [path stringByExpandingTildeInPath];
NSString * data = [NSString stringWithContentsOfFile:file];
NSArray * list = [data componentsSeparatedByString:@"\r"];
self = [super initWithCapacity: [list count]];
if (self) {
...
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Michael Ash1

External


Since: Jun 01, 2004
Posts: 525



(Msg. 4) Posted: Mon Oct 29, 2007 2:16 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

slashlos wrote:
> so I wasn't sure if the 'init' being called should be [self init] or
> [super init] but the immediate exception tells me I'm doing something
> wrong, but what?

Your [super init] call invokes NSArray's init method, completely bypassing
the NSMutableArray init method. As you would guess, things break very
badly when you do this.

As a general rule, you should only do [super init...] if you're invoking
the same initializer which you're implementing. Otherwise use self,
because if you don't you'll skip over the implementation for the class
you're in.

--
Michael Ash
Rogue Amoeba Software
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 5) Posted: Mon Oct 29, 2007 2:23 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Ah, we live and learn, I'll try that, thanks!

/los

glenn andreas wrote:
> The problem is that init is not a designated initializer for an
> NSMutableArray (or an NSArray for that matter). You should use
> initWithCapacity: instead in your "self = [super init]".
>
> You probably would want something like this:
>
> - (id)initWithContentsOfCSVFile:(NSString *)path
> {
> NSString * file = [path stringByExpandingTildeInPath];
> NSString * data = [NSString stringWithContentsOfFile:file];
> NSArray * list = [data componentsSeparatedByString:@"\r"];
> self = [super initWithCapacity: [list count]];
> if (self) {
> ...
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 6) Posted: Mon Oct 29, 2007 2:36 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Perhaps I mistyped, I didn't subclass it, I just created these files

csv.h
@interface NSMutableArray (csv)
- (id)initWithContentsOfCSVFile:(NSString *)path;
@end

csv.m
@implementation NSMutableArray (csv)
- (id)initWithContentsOfCSVFile:(NSString *)path
{
....
}
@end

and included the header in the caller.

Tom Harrington wrote:
> In article ,
> slashlos wrote:
>
>> I'm trying to write a category extension of NSMutableArray to load a
>> file which contains comma delimited lines of text. I have this:
>>
>> // Initialize newly alloc'd array with a comma separated values file
>> - (id)initWithContentsOfCSVFile:(NSString *)path
>> {
>
> Is that the only method you implemented? NSMutableArray's documentation
> lists several methods as being required in subclasses.
>
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
glenn andreas

External


Since: Oct 26, 2007
Posts: 6



(Msg. 7) Posted: Mon Oct 29, 2007 9:18 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article ,
Sherman Pendley wrote:

> glenn andreas writes:
>
> > The problem is that init is not a designated initializer for an
> > NSMutableArray (or an NSArray for that matter). You should use
> > initWithCapacity: instead in your "self = [super init]".
> >
> > You probably would want something like this:
> >
> > - (id)initWithContentsOfCSVFile:(NSString *)path
> > {
> > NSString * file = [path stringByExpandingTildeInPath];
> > NSString * data = [NSString stringWithContentsOfFile:file];
> > NSArray * list = [data componentsSeparatedByString:@"\r"];
> > self = [super initWithCapacity: [list count]];
>
> Wouldn't that be [self initWithCapacity: [list count]]? He's adding a
> category to NSMutableArray, not subclassing it.
>
> sherm--

Yup, that would be correct - "[self initWithCapacity:".

Funny how there's that subconscious program that runs when you haven't
had enough coffee that sees you typing "- (id)init..." and then forces
you to write "self = [super init..."
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Sherman Pendley

External


Since: Nov 06, 2007
Posts: 16



(Msg. 8) Posted: Mon Oct 29, 2007 9:25 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

glenn andreas writes:

> The problem is that init is not a designated initializer for an
> NSMutableArray (or an NSArray for that matter). You should use
> initWithCapacity: instead in your "self = [super init]".
>
> You probably would want something like this:
>
> - (id)initWithContentsOfCSVFile:(NSString *)path
> {
> NSString * file = [path stringByExpandingTildeInPath];
> NSString * data = [NSString stringWithContentsOfFile:file];
> NSArray * list = [data componentsSeparatedByString:@"\r"];
> self = [super initWithCapacity: [list count]];

Wouldn't that be [self initWithCapacity: [list count]]? He's adding a
category to NSMutableArray, not subclassing it.

sherm--

--
Web Hosting by West Virginians, for West Virginians: http://wv-www.net
Cocoa programming in Perl: http://camelbones.sourceforge.net
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Doc O'Leary

External


Since: Oct 07, 2007
Posts: 37



(Msg. 9) Posted: Tue Oct 30, 2007 7:30 am
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article ,
slashlos wrote:

> I'm trying to write a category extension of NSMutableArray to load a
> file which contains comma delimited lines of text.

You've already gotten direct answers so I'll take a different angle:
your whole approach is wrong. Nothing you're doing makes it
particularly necessary to muck with initialization of a Foundation
object. It seems to me you're just looking for a place to hang a
function. If it does make the most sense to add that behavior to
NSMutableArray, I'd suggest +arrayWithContentsOfCSVFile: as a cleaner
solution.

--
My personal UDP list: 127.0.0.1, 4ax.com, buzzardnews.com, googlegroups.com,
heapnode.com, localhost, ntli.net, teranews.com, vif.com, x-privat.org
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 10) Posted: Tue Oct 30, 2007 10:07 am
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Yes, you're right; I went Google'ng and found I'd actually asked this
question before (!) but and came upon the earlier recommendation, but
here the problem being solved was different. So I ended up with this:

+ (id)arrayWithContentsOfCSVFile:(NSString *)path
{
NSString * file = [path stringByExpandingTildeInPath];
NSString * data = [NSString stringWithContentsOfFile:file];
NSArray * list = [data componentsSeparatedByString:@"\r"];

if ([list count])
{
NSMutableArray * csvs = [[[NSMutableArray alloc]
initWithCapacity:[list count]] autorelease];
int i;

for (i=0; i<[list count]; i++)
{
NSString * line = [list objectAtIndex:i];
NSMutableArray * csv = [[NSMutableArray alloc] initWithArray:
[line componentsSeparatedByString:@","]];

// Add the CSV array not the line as text to our array
[csvs addObject:csv];
[csv release];
}
return csvs;
}
else
return nil;
}

But to further understand, if I had been extending the class I should be
using '[super init]' and if just a category extension, then '[self
init]'. I guess in this case the class I had chosen isn't appropriate
for either of those two approaches and as you indicated the above
approach makes it a bit easier - just wanted to understand the innards a
bit more.
--
/los "I was a teenage net-random"
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Michael Ash1

External


Since: Jun 01, 2004
Posts: 525



(Msg. 11) Posted: Tue Oct 30, 2007 10:07 am
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

slashlos wrote:
> NSMutableArray * csvs = [[[NSMutableArray alloc]
> initWithCapacity:[list count]] autorelease];

Just a small suggestion here. It won't matter much in this case, but it's
better to use [self alloc] rather than [NSMutableArray alloc]. This way if
you use this method with a subclass of NSMutableArray, you'll get an
instance of that subclass automatically.

> But to further understand, if I had been extending the class I should be
> using '[super init]' and if just a category extension, then '[self
> init]'.

That is wrong. You should *always* do [self init] unless you are
overriding the initializer you are calling. Not doing so risks bypassing
initializers in your class or your subclasses, and this is not a good
thing to do.

In other words, [self init] is preferred, nay required, unless there it
causes infinite recursion, in which case you obviously should avoid it and
use super.

--
Michael Ash
Rogue Amoeba Software
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 12) Posted: Tue Oct 30, 2007 4:17 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

two good points, thanks!

/los

Michael Ash wrote:
> slashlos wrote:
>> NSMutableArray * csvs = [[[NSMutableArray alloc]
>> initWithCapacity:[list count]] autorelease];
>
> Just a small suggestion here. It won't matter much in this case, but it's
> better to use [self alloc] rather than [NSMutableArray alloc]. This way if
> you use this method with a subclass of NSMutableArray, you'll get an
> instance of that subclass automatically.
>
>> But to further understand, if I had been extending the class I should be
>> using '[super init]' and if just a category extension, then '[self
>> init]'.
>
> That is wrong. You should *always* do [self init] unless you are
> overriding the initializer you are calling. Not doing so risks bypassing
> initializers in your class or your subclasses, and this is not a good
> thing to do.
>
> In other words, [self init] is preferred, nay required, unless there it
> causes infinite recursion, in which case you obviously should avoid it and
> use super.
>
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Sherman Pendley

External


Since: Nov 06, 2007
Posts: 16



(Msg. 13) Posted: Tue Oct 30, 2007 6:29 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

slashlos writes:

> But to further understand, if I had been extending the class I should
> be using '[super init]' and if just a category extension, then '[self
> init]'.

Close - very close. You should call the designated initializer, which is
not necessarily -init.

> I guess in this case the class I had chosen isn't appropriate
> for either of those two approaches

Sure it is. Nothing wrong with adding a new -initWithFoo: to a Foundation
class. It's just a question of whether you want to offer an initializer
method that returns an object that must be released (-initWithFoo:), or
a convenience method that returns an autoreleased object (+fooWithBar:).

sherm--

--
Web Hosting by West Virginians, for West Virginians: http://wv-www.net
Cocoa programming in Perl: http://camelbones.sourceforge.net
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
slashlos

External


Since: Nov 13, 2005
Posts: 111



(Msg. 14) Posted: Thu Nov 01, 2007 6:21 pm
Post subject: Re: Trouble extending NSMutableArray [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

well it wasn't working for the the -init... route but the +array... is
just dandy so I'm happy, thanks to all.

Sherman Pendley wrote:
> slashlos writes:
>
>> But to further understand, if I had been extending the class I should
>> be using '[super init]' and if just a category extension, then '[self
>> init]'.
>
> Close - very close. You should call the designated initializer, which is
> not necessarily -init.
>
>> I guess in this case the class I had chosen isn't appropriate
>> for either of those two approaches
>
> Sure it is. Nothing wrong with adding a new -initWithFoo: to a Foundation
> class. It's just a question of whether you want to offer an initializer
> method that returns an object that must be released (-initWithFoo:), or
> a convenience method that returns an autoreleased object (+fooWithBar:).
>
> sherm--
>
 >> Stay informed about: Trouble extending NSMutableArray 
Back to top
Login to vote
Display posts from previous:   
Related Topics:
help on extending a class - I'd like to extend NSMutableArray with this @interface NSMutableArray (CSVs) - (id)initWithContentsOfCSV:(NSString *)path; @end to allocate an array with objects from a comma delimited value set where each line of values in an object; when I tried t...

trouble compiling with qt - I am trying to compile qbrew ( http://www.usermode.org/code.html ) but it is failing on the qt check. I learned that qt must be installed and isn't by default so I used darwinports to get it installed. Now the qt check works, but the qt compilation..

Trouble with third C program - Hi everybody, I recently started learning C on the Mac. I wrote a short program that is supposed to output an ansii character code and its corresponding character. However, when compiled with gcc, I get a garbled output. Can someone look over my code...

newbie trouble: SequenceGrabber in CW - Hi I have an CW8 app that calls the SequenceGrabber functions in exactly the same way as in the HackTV sample of apple (thist works fine and secure). Sometimes my app works fine several times, then I get access fault errors in the QT calls to various..

Cocoa memory trouble - Although I think I have good handle on Cocoa memory managment, I still have some holes in my understanding. For example, in this code: NSEnumerator* e = [volumesArray objectEnumerator]; NSString* s = [[NSString alloc] init]; while(s =....
   Macintosh computer (Home) -> Programmer Help All times are: Pacific Time (US & Canada)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum



[ Contact us | Terms of Service/Privacy Policy ]