"Unrecognized selector" error when attempting to remove an object while in a for loop

Discussion in 'iOS Programming' started by moonman239, Feb 20, 2014.

  1. moonman239 macrumors 68000

    Joined:
    Mar 27, 2009
    #1
    Here's the deal. I'm trying to have the app remove an object from a mutable array while it is looping through another array. The object to be removed and the array that the object is to be removed from are both defined. However, I just got the following error message:

    Code:
    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
    '-[__NSArrayI removeObject:]: unrecognized selector sent to instance 0x95e6160
    
     
  2. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #2
    Sounds like the array is not mutable. How are you creating it? Note that if you save a mutable array to a plist or use NSCoding to save it, when you read it back, it's immutable.
     
  3. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #3
    You don't have a mutable array. Show us your code from the point where the array is created until you attempt to remove an object from it.
     
  4. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #4
    Here's what my code looks like

    Code:
    NSMutableArray *array1 = (NSMutableArray *)[array2 arrayByAddingObject:object];
    for (object in array3)
    {
    [array1 removeObject:definedObject];
    }
    

    The app crashes before it runs out of objects in array1.
     
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    NSArray's arrayByAddingObject: returns an NSArray. Just because you typecast it as a NSMutableArray does not make it mutable. I would look into using mutableCopy.
     
  6. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #6
    Update: After reading the Stack Overflow page entitled "Error: Mutating method sent to immutable object for NSMutableArray from JSON file," I figured out that simply casting an NSArray to an NSMutableArray does not produce an array that can be changed. I have to create a mutable copy of the immutable array and assign that array to the mutable array I mentioned in the post above.

    Edit:
    Thanks. I did not notice your post until now.
     
  7. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #7
    You can always try using [NSMutableArray arrayWithArray:array];
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    NSMutableArray doesn't have its own arrayWithArray: method, so that would still call the superclass NSArray's method (of which NSMutableArray is a subclass) and so the return value is still an (immutable) NSArray.
     
  9. EnderTW macrumors 6502

    Joined:
    Jun 30, 2007
    #9
    This.

    Also I suggest not using fast enumeration to add and/or remove objects.
     
  10. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #10
    I have found multiple sources that state using arrayWithArray: to get a NSMutableArray from a NSArray. I feel like I have also used it before with fine results. Am I doing something wrong here? I went back and read documentation and it seems you are right that arrayWithArray is just a method from the superclass, but I still feel like it worked for me in the past.
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #11
    Huh. Interesting. Well, I might be wrong here. A simple code test should be all it takes to verify whether that works or not. I'll let you know what I find.
     
  12. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #12
    arrayWithArray: should return an NSMutableArray, I believe, when invoked on an NSMutableArray. The method signature says that it returns an NSArray, which an NSMutableArray qualifies as.

    No, I didn't actually take the 5 minutes to set up a test for this.
     
  13. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #13
    I just tested it, and the NSMutableArray version of arrayWithArray does create a new mutable array.

    The NSArray class reference defines NSArray arrayWithArray: as

    Code:
    + (instancetype)arrayWithArray:(NSArray *)anArray
    
    That implies, in a very ambiguous fashion, that you get back an object of the type you created.
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #14
    Thanks for the update, Duncan. I guess that settles it. My apologies for possibly leading the OP astray.
     
  15. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #15
    The docs for NSMutableaArray should list a mutable array variant of the arrayWithArray method.

    ----------


    What does the type "instancetype" mean, anyway? Type of the target?
     
  16. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #16
    yes, as far as I recall instancetype means type of the target, and is used a lot in custom init methods instead of specifying -(id) return type

    Does this then mean that if you invoke it with [NSMutableArray arrayWithArray:someArray] it returns the type of NSMutableArray

    EDIT: What is interesting is that in the class reference for NSArray, under the method +(instancetype)array there is a note that states

    However that is not present for +(instancetype)arrayWithArray
     
  17. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #17

    Yes, when used like this:

    Code:
      NSArray *anArray = @[@"one", @"two", @"three"];
      NSMutableArray *aMut = [NSMutableArray arrayWithArray: anArray];
    
    The result is a mutable array.
     
  18. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #18
    Please report the doc-error to Apple, using the on-page feedback.

    Doc bugs are bugs. Report them so they can be fixed.
     
  19. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #19
    done
     

Share This Page