0

Possible Duplicate:
NSMutableArray Not showing actual values when NSLog in iphone application

I have NSMutableArray initialised as follows:

- (id)init
{
self = [super init];
if (self)
{
    mySpotsArray = [[NSMutableArray alloc]init];
}

return self;
}

The array stores data of NSTable as follows:

//-----------------------------------------
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [mySpotsArray count];

[self saveMySpots];
}


//-----------------------------------------
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn            *)tableColumn row:(NSInteger)row
{
Spot *sp = [mySpotsArray objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
return [sp valueForKey:identifier];

[self saveMySpots];
}



 //-----------------------------------------
 - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
Spot *sp = [mySpotsArray objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
[sp setValue:object forKey:identifier];

[self saveMySpots];
}

I am adding and deleting objects like this:

//-----------------------------------------
- (IBAction)addSpot:(id)sender
{
[mySpotsArray addObject:[[Spot alloc]init]];
[mySpotsTable reloadData];

[self saveMySpots];
}




//-----------------------------------------
- (IBAction)deleteSpot:(id)sender
{
NSInteger row = [mySpotsTable selectedRow];
[mySpotsTable abortEditing];
if (row !=-1)
{
    [mySpotsArray removeObjectAtIndex: row];
}

[mySpotsTable reloadData];

[self saveMySpots];
}

I am saving and loading array content like this:

//-----------------------------------------
- (void) saveMySpots
{
savedSpots = [NSUserDefaults standardUserDefaults];
encodedMySpotsArrayObject = [NSKeyedArchiver archivedDataWithRootObject: mySpotsArray];
[savedSpots setObject: encodedMySpotsArrayObject forKey:[NSString stringWithFormat:@"MySpotsArrayKey"]];
}




//-----------------------------------------
- (void) loadMySpots
{
savedSpots = [NSUserDefaults standardUserDefaults];
decodedMySpotsArrayObject = [savedSpots objectForKey: [NSString stringWithFormat:@"MySpotsArrayKey"]];

 mySpotsArray = [NSKeyedUnarchiver unarchiveObjectWithData: decodedMySpotsArrayObject];
}

Objects are encoded and decoded like this:

//-----------------------------------------
- (id)init
{
self = [super init];
if (self)
{
    _mySpot = @"My Spot";
    _localOffset = 0;
}

return self;
}


//-----------------------------------------
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject: self.mySpot forKey:@"MySpotKey"];
[encoder encodeInt: self.localOffset forKey:@"LocalOffsetKey"];
}



//-----------------------------------------
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if( self != nil )
{
    self.mySpot = [decoder decodeObjectForKey:@"MySpotKey"];
    self.localOffset = [decoder decodeIntForKey:@"LocalOffsetKey"];
}
return self;
}

Everything is properly defined in their respective .h like this

NSMutableArray *mySpotsArray;

NSUserDefaults *savedSpots;

NSData *encodedMySpotsArrayObject;
NSData *decodedMySpotsArrayObject;

All works perfect on UI level, i.e. the table is properly displayed, added, deleted, saved and loaded. But when I am trying to NSLog like this:

NSLog(@"%@", mySpotsArray);

I get this:

2012-09-19 13:41:25.372 Spot[1541:303] (
"<Spot: 0x100674ab0>",
"<Spot: 0x100674c20>",
"<Spot: 0x100675040>"
)

I've also tried this:

 NSString *strData = [[NSString alloc]initWithData: decodedMySpotsArrayObject encoding:NSUTF8StringEncoding];

NSLog(@"strData: %@", strData);

and I get this:

2012-09-19 13:41:25.371 Spot[1541:303] strData: (null)

I simply need to access NSMutableArray content and then convert it to strings. The actual content what I see on UI is a table with 2 columns and 3 rows:

Yerevan 2
London -1
Los Angeles -9

What am I doing wrong?

Thanks

Community
  • 1
  • 1
grep
  • 566
  • 5
  • 20
  • 3
    How about a **minimal, self-contained** example? – Kerrek SB Sep 19 '12 at 11:53
  • 1
    yeah, I've tried it yesterday and people complained that they can't help if they do not see code ... now it is too much code ... – grep Sep 19 '12 at 11:54
  • 1
    Correct. Life is all about finding the balance between too much and too little. If you're asking for water in a restaurant, you probably wouldn't appreciate it if the waiter dumps you into the fish pond. – Kerrek SB Sep 19 '12 at 11:55
  • 1
    @grep, Instead of the table view methods, it might help to see the Spot.h/.m file instead. Have you implemented a custom `description` method? –  Sep 19 '12 at 11:58
  • let me tell what i understand. You want to print your object in long in plain text format. am i right? – CRDave Sep 19 '12 at 12:02
  • Anna, the piece of code after sentence "Objects are encoded and decoded like this:" above is the content of Spot.m file. Should there be smth else. Sorry I am just learning ... – grep Sep 19 '12 at 12:03
  • @grep, I see now. Then the answer is what you need. –  Sep 19 '12 at 12:05
  • CRDave, basically yes, just to print NSArray content as I see on UI table – grep Sep 19 '12 at 12:06
  • possible duplicate of [NSMutableArray Not showing actual values when NSLog in iphone application](http://stackoverflow.com/questions/11732871/nsmutablearray-not-showing-actual-values-when-nslog-in-iphone-application). Notice that the solution you've gotten here is _indentical_ to the one there. That's why questions are closed as duplicates, as [your earlier one was](http://stackoverflow.com/questions/12483935/nslog-does-not-show-correct-values-of-nsarray). You weren't told that you needed to show the code, you were told that the question _was already answered_. – jscs Sep 20 '12 at 17:19

2 Answers2

3

I think this is the expected behavior.

How does the debugger know what it should print to the console? If you want it to print something else, e.g. some property on the Spot object, you need to provide Spot with a description method.

For example:

#import <Foundation/Foundation.h>

@interface Foo:NSObject {
    NSString *_bar;
}
@property (nonatomic, copy) NSString *bar;
@end

@implementation Foo
@synthesize bar = _bar;

- (NSString *)description {
    return self.bar;
}

@end

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

    NSMutableArray *objs = [[NSMutableArray alloc] init];
    Foo *myFoo = [Foo new];
    myFoo.bar = @"Mine";

    Foo *yourFoo = [Foo new];
    yourFoo.bar = @"Yours";

    [objs addObject:myFoo];
    [objs addObject:yourFoo];

    NSLog(@"Objs = %@",objs);

    [p release];
}

prints this to the console:

2012-09-19 06:57:10.375 Untitled 2[59494:707] Objs = (
    Mine,
    Yours
)

But without the description method, this is what prints to the console:

2012-09-19 07:01:12.542 Untitled 2[59853:707] Objs = (
    "<Foo: 0x7f9773c080c0>",
    "<Foo: 0x7f9773c0a9b0>"
)
FluffulousChimp
  • 9,157
  • 3
  • 35
  • 42
  • How do I add description method? – grep Sep 19 '12 at 12:04
  • In your `Spot` implementation. – FluffulousChimp Sep 19 '12 at 12:06
  • Thanks a lot, it worked for first column of table. How do I do the same for the second column, where the values are ints? – grep Sep 19 '12 at 12:13
  • ... string formatting, generally... – Jonathan Grynspan Sep 19 '12 at 12:35
  • what if i have NSString bar1 & bar2 , and want to NSLog(@"Obj1 = %@ Obj2 %@",[objs objectForKey:@"bar1"], [objs objectForKey:@"bar2"]); – Bishal Ghimire Jun 05 '13 at 07:15
  • It would be the same. The question and answers addressed the issue of what gets logged to the console with/without a `description` method on the object being logged. The variation you are inquiring is related to the collection class (`NSDictionary` vs `NSArray`) in which the logged objects are stored. In that case, just add the objects to a dictionary instead of an array... – FluffulousChimp Jun 05 '13 at 17:22
2

Add this method in your Spot class

- (NSString *)description
{
   NSString *str = [[NSString alloc] initWithFormat:@"%@ \n %@ \n%@",Var1,Var2,var3];

   return str;
}

replace Var1, Var2 and Var3 with your original variable name.

CRDave
  • 9,279
  • 5
  • 41
  • 59
  • Thanks CRDave, I've used the method from Alan and it worked, but it shows only content of 1st column. The table has 2 columns, 1 with strings and 2nd with ints, how can I achieve the same for the second column? – grep Sep 19 '12 at 12:20
  • The answer given by @CRDave is the answer. We don't know the structure of your `Spot` class, so you're going to have to extrapolate from what he's written above to your implementation. – FluffulousChimp Sep 19 '12 at 12:24
  • append that number with NSString str. – CRDave Sep 19 '12 at 12:25
  • Still need to learn a lot, but thank you anyway – grep Sep 19 '12 at 12:28