1

My problem is that I can access methods and attributes from the sharedInstance Singleton in one class but I cannot in another.

For example, the code below works and is recognized by X-code. Works fine. return [[[SINGLETON sharedInstance]baseballArray]count];

In addition to:

theSelectedBaseball = [[[SINGLETON sharedInstance]baseballArray]objectAtIndex:indexPath.row];

SINGLETON *singleton = [SINGLETON sharedInstance];
[singleton setSelectedBaseball:theSelectedBaseball];

However, if I try the code above in another class I get this warning message: - Method - setSelectedBaseball: not found.

I am importing the SINGLETON header in all of the classes that I want to use it. I looked closely at the class that it is being recognized versus the other class that it is not and I can't figure out why it is not being recognized.

Here is my Singleton Class.

#import <Foundation/Foundation.h>
#import "Baseball.h"

@interface SINGLETON : NSObject {

NSArray *baseballArray;
Baseball *selectedBaseball;
}

@property (nonatomic, retain) NSArray *baseballArray;
@property (nonatomic, retain) Baseball *selectedBaseball;

+ (SINGLETON*) sharedInstance;
- (void)setSelectedBaseball:(Baseball *)theBaseball;
- (Baseball*)getSelectedBaseball;

@end

Implementation:

#import "SINGLETON.h"
#import "Baseball.h"

@implementation SINGLETON

@synthesize baseballArray, selectedBaseball;
static SINGLETON *instance = nil;

+ (SINGLETON*)sharedInstance
{
@synchronized(self) {   
    if (instance == nil) {

        instance = [[SINGLETON alloc] init];
    }
    return instance;
}
}

- (void)setSelectedBaseball:(Baseball *)theBaseball
{
    selectedBaseball = theBaseball;  
}

- (Baseball*)getSelectedBaseball{
    return selectedBaseball;
}

- (id)init 
{
self = [super init];
if (self) {
    // created 5 Baseball Objects   
    // baseball array holding those 5 baseball objects
    baseballArray = [[[NSArray alloc] initWithObjects:Baseball1, Baseball2, Baseball3, Baseball4, Baseball5, nil] retain];

    // dealloced 5 Baseball Objects
}
return self;
}

+ (id)allocWithZone:(NSZone *)zone
{   
@synchronized(self) {       
    if (instance == nil) {

        instance = [super allocWithZone:zone];          
        return instance;  // assignment and return on first allocation
    }
}   
return nil; //on subsequent allocation attempts return nil  
}

- (id)retain
{   
return self;    
}

- (unsigned)retainCount
{
return UINT_MAX;  //denotes an object that cannot be released
}

- (id)autorelease
{
return self;    
}
- (void) dealloc
{
    [baseballArray release];
    [super dealloc];
}
@end
user819675
  • 23
  • 5

1 Answers1

6

A baseball is not a bracelet. You declare your properties as:

@property (nonatomic, retain) NSArray *baseballArray;
@property (nonatomic, retain) Charm *selectedBaseball;

...and then you synthesize:

@synthesize braceletArray, selectedBracelet;

...without ever marking baseballArray and selectedBaseball as @dynamic (if you intend to specify their getters/setters yourself), and without actually declaring any properties called "braceletArray" and "selectedBracelet".

Also, a Charm is also not a Baseball. You define inconsistent getter and setter methods:

- (void)setSelectedBaseball:(Baseball *)theBaseball;
- (Charm*)getSelectedBaseball; 

It seems to me like perhaps you are porting some class that used to work with charms and bracelets and modifying it so that it works with baseballs, and that you tried to build it when it was only halfway modified to work with baseballs.

I suggest completing your modifications so that all the types and property name are consistent between your interface and your implementation, and then seeing if you still see the missing selector problem.

aroth
  • 54,026
  • 20
  • 135
  • 176
  • It's not necessary to specify `@dynamic` if you're implementing the getter and setter according to the standard convention (which he is for the setter, anyway). – Chuck Jul 09 '11 at 01:58
  • @Chuck - Not required, but arguably in good style to use it anyways. Also, doesn't XCode report a compiler warning if it sees properties without a matching `@synthesize` or `@dynamic`? – aroth Jul 09 '11 at 07:48
  • @bbum - I have to disagree on the style part. Seeing `@dynamic ` tells me that "the getter and setter for `` are/should be implemented in this class and may override the standard semantics". Seeing `@synthesize ` tells me that "the getter and setter for `` are being generated automatically by the compiler and follow the standard semantics". Seeing neither is ambiguous. It says "the getter and setter may be defined in the class, or maybe the other dev just forgot to `@synthesize` the property". Ambiguity is never good coding style. – aroth Jul 10 '11 at 01:42
  • 1
    @aroth: `@dynamic` is there for when you won't have an implementation of the accessor until runtime, as with Core Data. If you implement the accessors properly, Xcode doesn't care whether your write `@synthesize`, `@dynamic` or nothing at all. And it's not as though the methods aren't right there in the method list. – Chuck Jul 10 '11 at 03:58
  • @aroth As Chuck said; `@dynamic` has a very explicit purpose and meaning. The compiler will complain loudly if an `@property` is not backed by `@synthesize`, `@dynamic` or manually implemented setter/getter method. When I read code that uses both `@dynamic` and manually implemented methods, it is a bug, I fix it, and I have a chat with the developer to make sure they understand the purpose of `@dynamic`. – bbum Jul 10 '11 at 05:08
  • Although that is a discrepancy, that wasn't my error. It was actually a bug with X-Code. Even though, I had the warnings I went ahead and tested the code. My getter and setters worked even with the warning of it possibly not being recognized. It seems that X-Code is not recognizing those methods prior to me running it. – user819675 Jul 11 '11 at 04:21