iPhone SDK Tableview Datasource singleton error

Posted by mrburns05 on Stack Overflow See other posts from Stack Overflow or by mrburns05
Published on 2010-06-11T03:05:42Z Indexed on 2010/06/11 3:12 UTC
Read the original article Hit count: 768

Filed under:
|
|
|

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

© Stack Overflow or respective owner

Related posts about iphone

Related posts about objective-c