I basically followed apple "TheElements" sample and changed "PeriodicElements" .h & .m to my own "SortedItems" .h & .m
During compile I get this error:
  "Undefined symbols:
  "_OBJC_CLASS_$_SortedItems",
  referenced from:
        __objc_classrefs__DATA@0 in SortedByNameTableDataSource.o ld:
  symbol(s) not found collect2: ld
  returned 1 exit status "
here is my SortedItems.m file
#import "SortedItems.h"
#import "item.h"
#import "MyAppDelegate.h"
@interface SortedItems(mymethods)
// these are private methods that outside classes need not use
- (void)presortItemsByPhysicalState;
- (void)presortItemInitialLetterIndexes;
- (void)presortItemNamesForInitialLetter:(NSString *)aKey;
- (void)presortItemsWithPhysicalState:(NSString *)state;
- (NSArray *)presortItemsByNumber;
- (NSArray *)presortItemsBySymbol;
- (void)setupItemsArray;
@end
@implementation SortedItems
@synthesize statesDictionary;
@synthesize itemsDictionary;
@synthesize nameIndexesDictionary;
@synthesize itemNameIndexArray;
@synthesize itemsSortedByNumber;
@synthesize itemsSortedBySymbol;
@synthesize itemPhysicalStatesArray;
static SortedItems *sharedSortedItemsInstance = nil;
+ (SortedItems*)sharedSortedItems {
    @synchronized(self) {
        if (sharedSortedItemsInstance == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedSortedItemsInstance;
 // note: Xcode (3.2) static analyzer will report this singleton as a false positive
 // '(Potential leak of an object allocated')
}
+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedSortedItemsInstance == nil) {
            sharedSortedItemsInstance = [super allocWithZone:zone];
            return sharedSortedItemsInstance;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone {
    return self;
}
- (id)retain {
    return self;
}
- (unsigned)retainCount {
    return UINT_MAX;  //denotes an object that cannot be released
}
- (void)release {
    //do nothing
}
- (id)autorelease {
    return self;
}
// setup the data collection
- init {
 if (self = [super init]) {
  [self setupItemsArray];
 }
 return self;
}
- (void)setupItemsArray {
 NSDictionary *eachItem;
 // create dictionaries that contain the arrays of Item data indexed by
 // name
 self.itemsDictionary = [NSMutableDictionary dictionary];
 // physical state
 self.statesDictionary = [NSMutableDictionary dictionary];
 // unique first characters (for the Name index table)
 self.nameIndexesDictionary = [NSMutableDictionary dictionary];
 // create empty array entries in the states Dictionary or each physical state
 [statesDictionary setObject:[NSMutableArray array] forKey:@"Solid"];
 [statesDictionary setObject:[NSMutableArray array] forKey:@"Liquid"];
 [statesDictionary setObject:[NSMutableArray array] forKey:@"Gas"];
 [statesDictionary setObject:[NSMutableArray array] forKey:@"Artificial"];
 MyAppDelegate *ad = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];
 NSMutableArray *rawItemsArray = [[NSMutableArray alloc] init];
 [rawItemsArray addObjectsFromArray:ad.items];
 // iterate over the values in the raw Items dictionary
 for (eachItem in rawItemsArray)
 {
  // create an atomic Item instance for each
  Item *anItem = [[Item alloc] initWithDictionary:eachItem];
  // store that item in the Items dictionary with the name as the key
  [itemsDictionary setObject:anItem forKey:anItem.title];
  // add that Item to the appropriate array in the physical state dictionary 
  [[statesDictionary objectForKey:anItem.acct] addObject:anItem];
  // get the Item's initial letter
  NSString *firstLetter = [anItem.title substringToIndex:1];
  NSMutableArray *existingArray;
  // if an array already exists in the name index dictionary
  // simply add the Item to it, otherwise create an array
  // and add it to the name index dictionary with the letter as the key
  if (existingArray = [nameIndexesDictionary valueForKey:firstLetter]) 
  {
   [existingArray addObject:anItem];
  } else {
   NSMutableArray *tempArray = [NSMutableArray array];
   [nameIndexesDictionary setObject:tempArray forKey:firstLetter];
   [tempArray addObject:anItem];
  }
  // release the Item, it is held by the various collections
  [anItem release];
 }
 // release the raw Item data
 [rawItemsArray release];
 // create the dictionary containing the possible Item states
 // and presort the states data
 self.itemPhysicalStatesArray = [NSArray arrayWithObjects:@"something",@"somethingElse",@"whatever",@"stuff",nil];
 [self presortItemsByPhysicalState];
 // presort the dictionaries now
 // this could be done the first time they are requested instead
 [self presortItemInitialLetterIndexes];
 self.itemsSortedByNumber = [self presortItemsByNumber];
 self.itemsSortedBySymbol = [self presortItemsBySymbol];
}
// return the array of Items for the requested physical state
- (NSArray *)itemsWithPhysicalState:(NSString*)aState {
 return [statesDictionary objectForKey:aState];
}
// presort each of the arrays for the physical states
- (void)presortItemsByPhysicalState {
 for (NSString *stateKey in itemPhysicalStatesArray) {
  [self presortItemsWithPhysicalState:stateKey];
 }
}
- (void)presortItemsWithPhysicalState:(NSString *)state {
 NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title"
                   ascending:YES
                 selector:@selector(localizedCaseInsensitiveCompare:)] ;
 NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor];
 [[statesDictionary objectForKey:state] sortUsingDescriptors:descriptors];
 [nameDescriptor release];
}
// return an array of Items for an initial letter (ie A, B, C, ...)
- (NSArray *)itemsWithInitialLetter:(NSString*)aKey {
 return [nameIndexesDictionary objectForKey:aKey];
}
// presort the name index arrays so the items are in the correct order
- (void)presortItemsInitialLetterIndexes {
 self.itemNameIndexArray = [[nameIndexesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
 for (NSString *eachNameIndex in itemNameIndexArray) {
  [self presortItemNamesForInitialLetter:eachNameIndex];
 }
}
- (void)presortItemNamesForInitialLetter:(NSString *)aKey {
 NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title"
                   ascending:YES
                 selector:@selector(localizedCaseInsensitiveCompare:)] ;
 NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor];
 [[nameIndexesDictionary objectForKey:aKey] sortUsingDescriptors:descriptors];
 [nameDescriptor release];
}
// presort the ItemsSortedByNumber array
- (NSArray *)presortItemsByNumber {
 NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"acct"
                   ascending:YES
                 selector:@selector(compare:)] ;
 NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor];
 NSArray *sortedItems = [[itemsDictionary allValues] sortedArrayUsingDescriptors:descriptors];
 [nameDescriptor release];
 return sortedItems;
}
// presort the itemsSortedBySymbol array
- (NSArray *)presortItemsBySymbol {
 NSSortDescriptor *symbolDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title"
                  ascending:YES
                   selector:@selector(localizedCaseInsensitiveCompare:)] ;
 NSArray *descriptors = [NSArray arrayWithObject:symbolDescriptor];
 NSArray *sortedItems = [[itemsDictionary allValues] sortedArrayUsingDescriptors:descriptors];
 [symbolDescriptor release];
 return sortedItems;
}
@end
I followed the sample exactly - don't know where I went wrong.
Here is my "SortedByNameTableDataSource.m"
    #import "SortedByNameTableDataSource.h"
#import "SortedItems.h"
#import "Item.h"
#import "ItemCell.h"
#import "GradientView.h"
#import "UIColor-Expanded.h"
#import "MyAppDelegate.h"
@implementation SortedByNameTableDataSource
- (NSString *)title {
 return @"Title";
}
- (UITableViewStyle)tableViewStyle {
 return UITableViewStylePlain;
};
// return the atomic element at the index 
- (Item *)itemForIndexPath:(NSIndexPath *)indexPath {
 return [[[SortedItems sharedSortedItems] itemsWithInitialLetter:[[[SortedItems sharedSortedItems] itemNameIndexArray] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
}
// UITableViewDataSource methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *MyIdentifier = @"ItemCell";
 ItemCell *itemCell = (ItemCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
 if (itemCell == nil) {
  itemCell = [[[ItemCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
        itemCell = CGRectMake(0.0, 0.0, 320.0, ROW_HEIGHT);
  itemCell.backgroundView = [[[GradientView alloc] init] autorelease];
 }
 itemCell.todo = [self itemForIndexPath:indexPath];
 return itemCell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 // this table has multiple sections. One for each unique character that an element begins with
 // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z]
 // return the count of that array
 return [[[SortedItems sharedSortedItems] itemNameIndexArray] count];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
 // returns the array of section titles. There is one entry for each unique character that an element begins with
 // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z]
 return [[SortedItems sharedSortedItems] itemNameIndexArray];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
 return index;
}
- (NSInteger)tableView:(UITableView *)tableView  numberOfRowsInSection:(NSInteger)section {
 // the section represents the initial letter of the element
 // return that letter
 NSString *initialLetter = [[[SortedItems sharedSortedItems] itemNameIndexArray] objectAtIndex:section];
 // get the array of elements that begin with that letter
 NSArray *itemsWithInitialLetter = [[SortedItems sharedSortedItems] itemsWithInitialLetter:initialLetter];
 // return the count
 return [itemsWithInitialLetter count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 // this table has multiple sections. One for each unique character that an element begins with
 // [A,B,C,D,E,F,G,H,I,K,L,M,N,O,P,R,S,T,U,V,X,Y,Z]
 // return the letter that represents the requested section
 // this is actually a delegate method, but we forward the request to the datasource in the view controller
 return [[[SortedItems sharedSortedItems] itemNameIndexArray] objectAtIndex:section];
}
@end