Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Samppaa

macrumors regular
Original poster
Mar 26, 2010
168
23
Hey guys I am doing a challenge in cocoa programming for os x third edition and when I am trying to add item to the array it won't show on the tableview, I know that tableview works properly as I tried to init it with speech synthentisator names and they showed, but somehow the items I try to add don't show, here is the code:

TableController.h
Code:
//
//  TableController.h
//  Challenge3
//
//  Created by Samuli Lehtonen on 8.6.2010.
//  Copyright 2010 Test. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface TableController : NSObject {
	NSMutableArray *items;
	IBOutlet NSTextField * itemField;
	IBOutlet NSTableView * tableView;

}

-(IBAction)addNewItem:(id)sender;

@end

TableController.m
Code:
//
//  TableController.m
//  Challenge3
//
//  Created by Samuli Lehtonen on 8.6.2010.
//  Copyright 2010 Test. All rights reserved.
//

#import "TableController.h"


@implementation TableController

-(int)numberOfRowsInTableView:(NSTableView *)tv
{
	return [items count];
}

-(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
	NSString *v = [items objectAtIndex:row];
	return v;
}

-(id)init
{
	[super init];
	NSLog(@"Init called!");
	return self;
}

-(IBAction)addNewItem:(id)sender
{
	NSLog(@"Additem called");
	[items addObject:[itemField stringValue]];
	
}

@end
 
Tell the tableview its content changed:

Code:
-(IBAction)addNewItem:(id)sender
{
	NSLog(@"Additem called");
	[items addObject:[itemField stringValue]];
	[self.tableView reloadData];
}
 
In addition to the above: where do you actually create an instance of NSMutableArray and assign it to items? Clearly it's not in the code you posted...
 
As people are saying above, declaring a NSMutableArray in your @interface section is not enough.

When you TableController object is created (presumably through -init) you basically have a hidden line of code that looks like
items = nil;

Thus when you're "adding" an object to this array, there is no array there and because ObjC doesn't give any errors when sending a message to nil, nothing happens.

In -init you need to create and assign an instance of NSMutableArray.
 
When you TableController object is created (presumably through -init) you basically have a hidden line of code that looks like
items = nil;

If only. items is not (I don't think) secretly initialised to nil. It will have whatever value was in that area of memory. This is way worse than nil...
 
Yeah, as with the others, it's probably your lack of initializing the array. Try adding;

Code:
items = [[NSMutableArray alloc] init];

into the init method for tableController. That should do it.
 
Ah, interesting. As a declared pointer in C is not guaranteed in a similar way.

C doesn't have instance variables. C++ does, and you're right on that point: no guaranteed initial value.

C does have static and local (automatic) variables. Static are guaranteed to be zero unless initialized otherwise. Local are not. Also true for Objective-C.

Allocated memory from malloc: no guarantee. Allocated memory from calloc: guaranteed zeros. True for C and Objective-C.
 
Untrue. alloc guarantees that all instance variables are zeroed.

I agree with you, I remember the Apple guy lecturing on the Stanford iTunes U CS193p course mentioning this.

But I would be leery of relying on this, since it's not prominently mentioned in the documentation and Apple could change it at any time. Maybe Xcode 4 does this, maybe it doesn't. Or maybe I'm paranoid.
 
But I would be leery of relying on this, since it's not prominently mentioned in the documentation and Apple could change it at any time. Maybe Xcode 4 does this, maybe it doesn't. Or maybe I'm paranoid.

It's a widely-known and well-documented feature. There's no possible way Apple could change this now. There's way too much existing code that relies on this. It would all break.

I don't know how prominently mentioned you think it needs to be. It's a very simple concept, so it doesn't need a lot of discussion in the docs.

From the reference doc on +alloc in NSObject reference (emphasis added):
The isa instance variable of the new instance is initialized to a data structure that describes the class; memory for all other instance variables is set to 0. The new instance is allocated from the default zone—use allocWithZone: to specify a particular zone.
http://developer.apple.com/mac/libr...rence.html#//apple_ref/occ/clm/NSObject/alloc
The same wording appears for +allocForZone:.
 
I agree with you, I remember the Apple guy lecturing on the Stanford iTunes U CS193p course mentioning this.

But I would be leery of relying on this, since it's not prominently mentioned in the documentation and Apple could change it at any time. Maybe Xcode 4 does this, maybe it doesn't. Or maybe I'm paranoid.

You 100% CAN rely on this. And this is documented, even if you have to read between the lines.

Lets take a look at a method for accessing a NSPersistentStoreCoordinator that is auto generated in the template for CoreData applications.

Code:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
	
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
	
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"SuperDB.sqlite"]];
	
	NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
		NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
		abort();
    }    
	
    return persistentStoreCoordinator;
}

This relies on the ivar persistentStoreCoordinator == nil when the object is created. This is called "lazy loading", and is a technique throughout Apple's, and my own, codebase.
 
Really, why would Apple not use calloc()? If they do use calloc() to create memory blocks for NSObject-based classes, why would one not be able to rely on zeroed initialization? The reason local variables have unknown initial values is because they live on the stack, which is a heavily used, constantly changing memory region.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.