1

This is my code.

NSString* seats = @"NEWS";
NSMutableString *sp = [[NSMutableString alloc] initWithString:@"             "];
NSArray *dials=@[@[sp, sp, sp, sp], @[sp, sp, sp, sp]];
[dials[0][2] replaceCharactersInRange:NSMakeRange(5, 1) withString:[seats substringWithRange:NSMakeRange(3,1)]];
NSLog(@"dial 0 0 : %@",dials[0][0]);
NSLog(@"dial 0 1 : %@",dials[0][1]);
NSLog(@"dial 0 2 : %@",dials[0][2]);
NSLog(@"dial 0 3 : %@",dials[0][3]);

This is my console readout.

2013-02-08 08:23:26.114 [29075:11303] dial 0 0 :      S       
2013-02-08 08:23:26.115 [29075:11303] dial 0 1 :      S       
2013-02-08 08:23:26.115 [29075:11303] dial 0 2 :      S       
2013-02-08 08:23:26.115 [29075:11303] dial 0 3 :      S       

How can I instead get the following readout, which is what I want?

2013-02-08 08:23:26.114 [29075:11303] dial 0 0 :              
2013-02-08 08:23:26.115 [29075:11303] dial 0 1 :              
2013-02-08 08:23:26.115 [29075:11303] dial 0 2 :      S       
2013-02-08 08:23:26.115 [29075:11303] dial 0 3 :              
zerowords
  • 2,915
  • 4
  • 29
  • 44

1 Answers1

3

By just doing this:

NSArray *dials=@[@[sp, sp, [sp mutableCopy], sp], @[sp, sp, sp, sp]];

Got why? If you think well that array just contains duplicate objects. Every pointer is pointing to the same object except dials[0][2], which points to a copied object.

Putting duplicate objects in the same array is allowed, but it may be conceptually wrong. So also consider copying all the objects.

Another solution would be to replace your immutable array with mutable strings with a mutable array with immutable strings, and in this case you could also put duplicate objects, and to change an object you should replace it:

NSString *sp = @"             ";
NSArray*dials=@[[@[sp, sp, sp, sp]mutableCopy], [@[sp, sp, sp, sp]mutableCopy]];
NSString* replace= [dials[0][2] stringByReplacingCharactersInRange:NSMakeRange(5, 1) withString:[seats substringWithRange:NSMakeRange(3,1)]];
[dials[0] replaceObjectAtIndex: 2 withObject: replace];
Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • 1
    Good answer! However it's a *set* which cannot have the same object multiple times and I don't see any issue with duplicate objects within an *array* (other than how the OP has used it in this case). – trojanfoe Feb 08 '13 at 14:07
  • Yes, I agree it can have multiple objects, but I'm saying it's conceptually debatable. – Ramy Al Zuhouri Feb 08 '13 at 14:10
  • Because I want to edit every individual space, altho I just showed the one position to make my point, do you mean that dials needs to be created with `[sp mutableCopy]` in every position? And, is there some trick to doing that other than a brute force definition like the one I am using? Also if you have the time, I would like to define the whole dial in another class `BSParam.h/.m`to be included here, but have been unable to do that. Could you say how? How's that for adding questions? – zerowords Feb 08 '13 at 14:14
  • Yes: immutable array with mutable strings. Or the other, IMHO classy solution would be a mutable array with immutable strings, so that every time that you want to change a string you just replace it. – Ramy Al Zuhouri Feb 08 '13 at 14:21
  • Yes, I started with the "classy" approach but found that `NSString` has no `replaceCharactersInRange` option and decided on `NSMutableString`. – zerowords Feb 08 '13 at 14:28
  • 1
    It hasn't this method because it's immutable. Use stringByReplacingCharactersInRange to create another object and replace it. Added an example in the edited answer. – Ramy Al Zuhouri Feb 08 '13 at 14:29
  • `dials` is really [36][4], not [2][4] and I have already implemented successfully the first method. This process only takes place once a day on an iOS device in practice so timing may not be a critical issue, but do you think the alternative way would be much more time friendly and enough so for me to use the alternative method? – zerowords Feb 08 '13 at 16:05
  • How many strings do you modify in your code? – Ramy Al Zuhouri Feb 08 '13 at 16:26
  • Each string is modified 13 times, and there are 144 (36x4) of the strings, so I guess thats 1872. – zerowords Feb 08 '13 at 16:34
  • At this point I suggest to use all immutable strings. – Ramy Al Zuhouri Feb 08 '13 at 21:15
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24213/discussion-between-ramy-al-zuhouri-and-zerowords) – Ramy Al Zuhouri Feb 08 '13 at 21:15
  • I am not familiar with the chat room and I wanted to experiment more with your recommendation. If you are interested I can time both of the approaches if someone tells me how to do timings. – zerowords Feb 11 '13 at 20:23
  • Ok, but you should also look at memory consumption. For timing I suggest to watch the number of clocks, with clock_t clock(void); You can then compute the time by knowing the macro CLOCKS_PER_SEC. Or use time profiler which tells you the percentage of time usage of every call. – Ramy Al Zuhouri Feb 11 '13 at 20:29
  • I cannot follow your instructions for timing. But let's forget that. I used the Allocations Instrument and got for All Allocation for Live Bytes 1.12 and 1.14MB, with your suggestion producing the lower number. So I guess that your approach was worth using. Thanks. Wait. I found a link on SO that showed how to [clock time](http://stackoverflow.com/questions/5248915/execution-time-of-c-program) and the time is 1.18 for your method and 0.23 for mine. Whereas that is significant, this process happens very infrequently, so is not really an issue. – zerowords Feb 12 '13 at 01:03