-1

I am having some issues with singletons in objective-c. Though I have not seen an example of this in objective-c, I decided to facilitate communication between ViewControllers using singletons. From what I understand this is not the encouraged way of communicate between view controllers, but I figured I would give it a shot.

So, for my singleton I have:

+(FirstViewController*) getInstance;

defined in the header file. This will allow outside callers to get to it. The implementation is as follows:

 static FirstViewController* _instance;
 +(FirstViewController*) getInstance
 {
      //I assume there will be only one copy of this throughout the project, so        
      //pointer confusion is not an issue here, hens it being a singleton
      if (_instance == nil)
      {
           _instance = (FirstViewController*)self;
      }

      return _instance;
 }

The first hint that this is may cause trouble is that the XCode complains that I am setting the instance pointer to self. The warning is:

 Incompatible pointer types assigning to "FirstViewController*" from 'class'

Ok, warning noted, looks like I am trying to apply one pointer to another. Casting this to FirstViewController makes the warning go away (since it is now the correct pointer type), but it does not hurt to remember that this maybe a root of possible future issues .

In the FirstViewController I have a function

-(void)assignWord:(NSString *)w

I should be able to get to this through the singleton instance. In my second view controller I invoke this by:

FirstViewController* controller = [FirstViewController getInstance];
[controller assignWord:string];

however, this ends up crashing. To be more specific:

+[FirstViewController assignWord:]: unrecognized selector sent to class

One thing that is very strange about this is that it is trying to call this as a static function, rather than inside an instance.

Another thing that I have noticed while stepping through this during debugging, is that the _instance variable remains nil when I set the break point to the return of the singleton

 self   Class   FirstViewController 0x0000000100006b98
_instance   SecondViewController *  nil 0x0000000000000000

one thing that is a bit odd is that _instance is seen as the SecondViewController; my guess is it has something to do with the caller.

I don't do objective-c very often. Has anyone else come across this? Have any idea of why I am getting strange behavior? (is the debugger reliable enough?)

Note: The string pointer being passed is a valid NSString

johnbakers
  • 24,158
  • 24
  • 130
  • 258
Serguei Fedorov
  • 7,763
  • 9
  • 63
  • 94
  • 6
    `self` will not be a `FirstViewController *` in a class method (which is exactly what the error says). Don't cast away pointer errors. – sapi Sep 29 '13 at 08:27
  • 6
    Not an Xcode question. -------- Read a basic Objective-C tutorial: you will find that inside class methods, `self` refers to the class. (How possibly could it refer to an instance anyway, when there is no instance?) –  Sep 29 '13 at 08:28
  • Talk about being stupid. I put self in a static method, woohoo! It's late – Serguei Fedorov Sep 29 '13 at 08:29
  • Strange thing about Obj-C versus other similar languages like Java: `self` isn't always the same thing. In `+` methods, `self` is a reference to the class, not an instance of the class. That way, you can call other `+` methods like `[self otherClassMethod]`. – Ky - Dec 09 '15 at 16:38

2 Answers2

1

You should be initializing _instance in your if (_instance == nil). After all, if _instance is nil, then it doesn't exist and you need to make it exist by actually allocating memory. Your statement _instance = (FirstViewController*)self; doesn't do any of this.

Secondly, this is a class method, not an instance method, therefore self doesn't have the meaning you probably expect: it is not an instance of anything (and therefore cannot refer to a singleton instance).

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • Your statement that "`self` has no meaning" in a class method is incorrect. In Objective-C, `self` is always the receiver of the message, so in a class method, `self` is the class that received the message. – jlehr Sep 29 '13 at 17:27
0

Change your _instance = (FirstViewController*)self; to

_instance = [[FirstViewController alloc] init]
CodeHelp
  • 1,328
  • 5
  • 21
  • 37
  • Why? A good answer is more thna an answer, but instructions on how to avoid the problem in the future – Ky - Dec 09 '15 at 16:36