ERROR for attempting mutating immutable object

Discussion in 'Mac Programming' started by saleh.hi.62, Nov 25, 2011.

  1. saleh.hi.62, Nov 25, 2011
    Last edited: Nov 25, 2011

    macrumors member

    Joined:
    Jul 25, 2011
    #1
    what is this error? i am using mutable type but still it does not work!

    ERROR IS :
    Code:
    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'mutate immutable object with deleteCharactersInRange:
    Code is :
    Code:
    NSMutableString *line= [NSMutableString stringWithString:@"here is the string"];
    [line deleteCharactersInRange: NSMakeRange(1,9 )];
     
  2. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #2
    You can't seriously expect us to believe that that's the code that is throwing that exception, can you?
     
  3. thread starter macrumors member

    Joined:
    Jul 25, 2011
    #3
    you try to copy and paste it in ur XCODE and see what will be the result.
     
  4. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    No, but there's got to be something between those two lines!


    Look if you getting this exception then at some point you've assigned an NSString object into line.

    If you want to confirm, log the actual class of the thing line is pointing to just before when you send it deleteCharactersInRange:.
     
  5. macrumors 603

    Joined:
    Aug 9, 2009
    #5
    test1.m
    Code:
    #import <Foundation/Foundation.h>
    
    int main( int argc, char *argv[] )
    {
    	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    [COLOR="Red"]NSMutableString *line= [NSMutableString stringWithString:@"here is the string"];
    [/COLOR]	NSLog( @"before: %@, len: %d", line, [line length] );
    [COLOR="red"][line deleteCharactersInRange: NSMakeRange(1,9 )];
    [/COLOR]	NSLog( @"after: %@, len: %d", line, [line length] );
    	
    	[pool drain];
    	return 0;
    }
    
    
    Your posted code is hilited in red. It's exactly as you posted it.

    Output:
    Code:
    2011-11-25 11:04:21.794 test1[8680] before: here is the string, len: 18
    2011-11-25 11:04:21.795 test1[8680] after: he string, len: 9
    
    Result: It works perfectly.

    You should compile and run it yourself to confirm this result.

    I hope this has demonstrated the value of writing tests. And then compiling and running them.
     
  6. jiminaus, Nov 25, 2011
    Last edited: Nov 25, 2011

    macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #6
    I'd misread this sentence. I thought you were complaining about what would be results of copying and pasting your whole XCode project into a post.

    If I copy and paste those two lines into main, I get:

    *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString deleteCharactersInRange:]: Range or index out of bounds'

    Which is perfectly understandable given that you've initialised your mutable string with length 0 and then tried to deleted characters from it.

    And that's the kind of exception I knew that your code was going to produce. I could see straight away that it wasn't going to produce an exception about mutating an immutable object.

    That's why I didn't waste my time at first actually running your code. And I'll thank you not to again waste mine, and others, time by not posting actual post relevant to your problem.


    Ahhh, and now I've noticed you've edited your original post.
    For the record, the original code posted was:
    Code:
    NSMutableString *line = [NSMutableString stringWithCapacity:0];
    [line deleteCharactersInRange:NSMakeRange(1, 9)];
    
     
  7. macrumors 603

    Joined:
    Aug 9, 2009
    #7
    Wow. OP wins two Fail Whales. One for editing the original code to look less, well, failing. Two for editing it so it actually works, but still complaining: "you try to copy and paste it in ur XCODE and see what will be the result." (Look at the timestamps on the edit vs. the one on the complaint.)
     
  8. macrumors 603

    Joined:
    Aug 9, 2009
    #8
    I've been trying to produce the "mutate immutable object" error.

    Given this code:
    Code:
    NSMutableString *line= [NSMutableString stringWithString:@"here is the string"];
    [line deleteCharactersInRange: NSMakeRange(1,9 )];
    here's one way to produce that error:
    Code:
    NSMutableString *line= [[COLOR="Blue"]NSString[/COLOR] stringWithString:@"here is the string"];
    [line deleteCharactersInRange: NSMakeRange(1,9 )];
    The blue hilite indicates the change, whose effects should be obvious to anyone who understands the fundamentals of mutable/immutable Foundation classes.

    This change also fails:
    Code:
    NSMutableString *line= @"here is the string";
    [line deleteCharactersInRange: NSMakeRange(1,9 )];
    which should be as much of a surprise as water being wet.
     
  9. saleh.hi.62, Nov 25, 2011
    Last edited: Nov 25, 2011

    thread starter macrumors member

    Joined:
    Jul 25, 2011
    #9
    I ought to put the complete code here at first, i am sorry that posted this question incomplete!

    here is the whole code:


    Code:
    	NSRange range;
    	NSURL *url=[NSURL URLWithString:@"http://www.msn.com/robots.txt"];
    	
    	NSString *content = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    	
    	NSArray *parsed = [content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    	
    	NSMutableArray *robots=[[[NSMutableArray alloc] init] autorelease];
    	
    	NSMutableString *line= [[[NSMutableString alloc] init] autorelease];
    	
    	
    	for(line in parsed){
    		range=[line rangeOfString:@"Disallow"];
    		if (range.location != NSNotFound) {
    			[line deleteCharactersInRange: NSMakeRange(1,9 )];
    			[robots addObject:line];
    			
    		}
    	}		
    
     
  10. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #10
    http://developer.apple.com/library/...SString/componentsSeparatedByCharactersInSet:

    Does that say the list will be of mutable strings? Especially if you pass this to an immutable string?

    You can easily just get a substring rather than modifying the immutable string in-place. I'd do that and store the new substring and be done with it.

    -Lee

    Edit: Also, robots needs to be an array, you alloc/init a mutable string and assign it there.
     
  11. thread starter macrumors member

    Joined:
    Jul 25, 2011
    #11
    yes the error is what you mentioned. i revised it. but ! the what i am trying to do is that i want delete "Disallow" from all the elements in my array, any solution?
     
  12. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #12
  13. chown33, Nov 26, 2011
    Last edited: Nov 26, 2011

    macrumors 603

    Joined:
    Aug 9, 2009
    #13
    The solution is to Follow the robot exclusion standard.

    That means when the robots.txt file says "Disallow", you follow that exclusion. You don't delete the word "Disallow" and go on a malicious webcrawling spree.

    If you're going to make a webcrawler, you should cooperate with the websites you're crawling. Don't be a bad web citizen. For example, read Wikipedia's robots.txt file. Notice all the bad citizens who are disallowed.


    At this point, I'm no longer going to give you any programming advice.

    I recommend that everyone else be aware that you're asking how to make an ill-behaved and possibly malicious webcrawler. It's the only logical reason I can think of for removing Disallow from robots.txt files.
     
  14. thread starter macrumors member

    Joined:
    Jul 25, 2011
    #14
    yes, i am trying to write a web crawler, but what i am trying to is to have the Disallow links in any array to avoid crawling them, so i want to remove the word disallow then store it in array. not doing something else! ;)
     

Share This Page