fetching from NSArray

  • I'm adding NSString objects in NSArray (for storage) and then trying to
    remove certain ranges from NSArray and then outputting them via NSTextview. I
    keep getting errors and not sure why.  I am fairly new to cocoa and
    obj C.  What
    is the easiest way to remove objects from an array in objective C ?
    Is it (getObjects:range)?

    Relevant Code:

    newLine = [[NSString alloc] initWithFormat:@"%0.07d:  %@\n", m_lineNumber,
    newLine];

    m_lineNumber++; //becomes index of array

    [m_storage addObject:newLine];

    NSString *temp1;

    NSAttributedString *attributedLine;

    id* aBuffer;

    Range.location = (1500*user_page);  //the range is 1500 cells in array

    Range.length = 1500;

      [m_storage getObjects:aBuffer range:Range];

    temp1 = *aBuffer;  (At this point, temp1 points to the relevant location as
    seen in debugger)

    attributedLine = [[NSAttributedString alloc] initWithString:temp1
    attributes:[NSMutableDictionary dictionary]];

    [g_pMainStorage setAttributedString:attributedLine];

    *Error:*

    Program received signal:  "EXC_BAD_ACCESS".

    Unable to disassemble .objc_class_name_NSCustomPredicateOperator.
  • On Oct 2, 2007, at 3:23 PM, Erfan Aleemullah wrote:

    > id* aBuffer;

    Here you're declaring a pointer to a pointer, which is probably not
    what you want. Use "id aBuffer" instead.

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • So, I'm storing NSString objects in each array index and then, I need to
    access them again so I fetch the objects based on a user range - which can
    range up to 1500 cells of the array.the ' &aBuffer ' worked, but only when i
    fetched one object - and the program crashed with

    Previous frame inner to this frame (gdb could not unwind past this frame)

    Previous frame inner to this frame (gdb could not unwind past this frame)

    Program received signal:  "EXC_BAD_ACCESS".

    when i fetched more than one object as defined by the Range variable.  Do I
    need to allocated memory or size or something to fetch several objects at
    one time ?

    thanks.

    On 10/2/07, Nick Zitzmann <nick...> wrote:
    >
    >
    > On Oct 2, 2007, at 3:56 PM, Erfan Aleemullah wrote:
    >
    >> didn't work.
    >>
    >> id aBuffer;
    >> [m_storage getObjects:aBuffer range:Range];
    >> warning:passing argument 1 of 'getObjects:range:' from incompatible
    >> pointer type
    >>
    >> What method should I be using to extract from NSArray ?
    >
    > You need to pass in a pointer to aBuffer, like this:
    >
    > [m_storage getObjects:&aBuffer range:Range];
    >
    > But exactly what are you trying to do? I've never had to use that
    > method before.
    >
    > Nick Zitzmann
    > <http://www.chronosnet.com/>
    >
    >
  • Please don't send off-list replies back to the list! That's rude.

    On Oct 2, 2007, at 4:36 PM, Erfan Aleemullah wrote:

    > when i fetched more than one object as defined by the Range
    > variable.  Do I need to allocated memory or size or something to
    > fetch several objects at one time ?

    It's possible that you may need to pre-allocate the memory space (as
    I've said, I've never used the method, and the documentation says
    nothing about it), although if you really need a subset of objects,
    then you might want to consider using -objectsAtIndexes: instead
    using an NSIndexSet with the given range. At least that won't have
    the memory problems...

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Oct 2, 2007, at 5:23 PM, Erfan Aleemullah wrote:
    > [m_storage getObjects:aBuffer range:Range];

    Bizarre -- the docs for -getObjects:, -getObjects:range:, and
    +arrayWithObjects:count: give no clue that I can find about what the
    aBuffer argument is supposed to be.  I'm trying to imagine why on
    earth it would be an id*.

    I've submitted feedback about this via the link at the bottom of the
    NSArray doc page.

    --Andy
  • On Oct 2, 2007, at 4:04 PM, Andy Lee wrote:

    > On Oct 2, 2007, at 5:23 PM, Erfan Aleemullah wrote:
    >> [m_storage getObjects:aBuffer range:Range];
    >
    > Bizarre -- the docs for -getObjects:, -getObjects:range:, and
    > +arrayWithObjects:count: give no clue that I can find about what the
    > aBuffer argument is supposed to be.  I'm trying to imagine why on
    > earth it would be an id*.

    They do exactly what the docs say they do — copy the pointers from the
    NSArray to a buffer. So the buffer should be a pointer to a pointer,
    that is, an id*. The program is crashing because you haven't allocated
    any memory for the buffer.

    I suppose the standard question applies of "what do you really want to
    do?" The set of situations where any of the buffer-related methods in
    the Foundation collections are genuinely useful is pretty small.

    -> jp
  • --- Andy Lee <aglee...> wrote:

    > On Oct 2, 2007, at 5:23 PM, Erfan Aleemullah wrote:
    >> [m_storage getObjects:aBuffer range:Range];
    >
    > Bizarre -- the docs for -getObjects:,
    > -getObjects:range:, and
    > +arrayWithObjects:count: give no clue that I can
    > find about what the
    > aBuffer argument is supposed to be.  I'm trying to
    > imagine why on
    > earth it would be an id*.

    I'm not at a computer where I can test it, but I
    assume it's a standard C array:

    id *buffer = calloc(numberOfItemsIWantToFetch,
    sizeof(id));
    [myArray getObjects:buffer range:rangeOfItems];

    Cheers,
    chuck


    ____________________________________________________________________________________
    Building a website is a piece of cake. Yahoo! Small Business gives you all the tools to get online.
    http://smallbusiness.yahoo.com/webhosting
  • On Oct 2, 2007, at 7:17 PM, Charles Steinman wrote:
    > I'm not at a computer where I can test it, but I
    > assume it's a standard C array:

    Oh, that would make sense.  For some reason the first thing I thought
    of was that the id* was to return a single id by reference, in which
    case it would have made more sense to simply return it by value.  But
    returning a C array makes sense by analogy to NSString's -
    getCharacters:range:.  The documentation should therefore be similar
    IMO.

    --Andy
  • On Oct 2, 2007, at 6:39 PM, Andy Lee wrote:

    > On Oct 2, 2007, at 7:17 PM, Charles Steinman wrote:
    >> I'm not at a computer where I can test it, but I
    >> assume it's a standard C array:
    >
    > Oh, that would make sense.  For some reason the first thing I
    > thought of was that the id* was to return a single id by reference,
    > in which case it would have made more sense to simply return it by
    > value.  But returning a C array makes sense by analogy to
    > NSString's -getCharacters:range:.  The documentation should
    > therefore be similar IMO.

    That's definitely a strange API:

    NSArray* theArray = [NSArray arrayWithObjects:@"a", @"b", @"c", @"d",
    @"e", nil];

    NSLog (@"theArray = %@", theArray);

    id p = calloc (2, sizeof (id));

    [theArray getObjects:&p range:NSMakeRange (1, 2)];

    NSString* theFirstString = (NSString*) p;
    p += sizeof (id);
    NSString* theSecondString = (NSString*) p;

    NSLog (@"theFirstString = %@", theFirstString);
    NSLog (@"theSecondString = %@", theSecondString);

    output:

    theArray = (a, b, c, d, e)
    theFirstString = b
    theSecondString = a

    I tried other locations for the range too; the order of objects
    returned is backwards as I would have expected :)  Of course, I
    haven't yet tried this with three or more objects, so do not know if
    getObjects is always returning objects in the opposite order of
    storage in the array, or if the order is just random.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On Oct 2, 2007, at 7:58 PM, Ricky Sharp wrote:

    >
    > On Oct 2, 2007, at 6:39 PM, Andy Lee wrote:
    >
    >> On Oct 2, 2007, at 7:17 PM, Charles Steinman wrote:
    >>> I'm not at a computer where I can test it, but I
    >>> assume it's a standard C array:
    >>
    >> Oh, that would make sense.  For some reason the first thing I
    >> thought of was that the id* was to return a single id by
    >> reference, in which case it would have made more sense to simply
    >> return it by value.  But returning a C array makes sense by
    >> analogy to NSString's -getCharacters:range:.  The documentation
    >> should therefore be similar IMO.
    >
    > That's definitely a strange API:

    The strange output is the result of using it incorrectly. :-(

    > NSArray* theArray = [NSArray arrayWithObjects:@"a", @"b", @"c",
    > @"d", @"e", nil];
    >
    > NSLog (@"theArray = %@", theArray);
    >
    > id p = calloc (2, sizeof (id));

    Id is a pointer to a single object. To allocate an array of them on
    the heap, you'd:

        id* p = calloc(2, sizeof(id));

    Or, to allocate it on the stack:

        id p[2];

    > [theArray getObjects:&p range:NSMakeRange (1, 2)];

    Now, since p is already either an id* or an id[], which amount to the
    same thing, you don't need to take its address:

            [theArray getObjects:p range:NSMakeRange (1, 2)];

    > NSString* theFirstString = (NSString*) p;
    > p += sizeof (id);
    > NSString* theSecondString = (NSString*) p;

    Playing around with pointer arithmetic only serves to confuse the
    issue - it would be much clearer to use a simple array subscript.
    With that in mind, here's a working example:

    #import <Foundation/Foundation.h>

    int main(int argc, char **argv) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

        NSArray *theArray = [NSArray arrayWithObjects:@"a", @"b", @"c",
    @"d", @"e", nil];
        NSLog (@"theArray = %@", theArray);

        // id *p = calloc(2, sizeof(id));
        id p[2];

        [theArray getObjects:p range:NSMakeRange (1, 2)];

        NSLog (@"theFirstString = %@", p[0]);
        NSLog (@"theSecondString = %@", p[1]);

        [pool release];

        return 0;
    }

    And its output:

    2007-10-02 21:22:04.507 testme[24706] theArray = (a, b, c, d, e)
    2007-10-02 21:22:04.507 testme[24706] theFirstString = b
    2007-10-02 21:22:04.507 testme[24706] theSecondString = c

    sherm--

    Web Hosting by West Virginians, for West Virginians: http://wv-www.net
    Cocoa programming in Perl: http://camelbones.sourceforge.net
  • Update:  id *buffer = calloc(numberOf_ItemsIWant_ToFetch,sizeof(id));[myArray
    getObjects:buffer range:rangeOfItems]

    So, using this code solves my problem of fetching items from an NSArray,
    after defining the NSRange variable.    Yes, as someone suggested earlier
    on, its a pointer to a pointer ... or in my case a pointer array, where each
    item is stored in buffer[i]
    thanks !
  • > Update:  id *buffer = calloc(numberOf_ItemsIWant_ToFetch,sizeof(id));
    > [myArray
    > getObjects:buffer range:rangeOfItems]

    No reason to use calloc here; since you’re going to be filling in
    values, the zero-filling will just be a waste of time. Use
    malloc(numberOf_ItemsIWant_ToFetch * sizeof(id)) instead.

    -Ben
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today