-1

I want to create a private global variable in an NSObject class. Here is what I have so far:

+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

I want to create and assign an NSDictionary that can be accessed throughout the .m file.

For example: In a regular .m UIViewController class, there is:

@interface MyViewControllerClassName ()

// Here I would declare private global variables.
// Example:
@property (strong, nonatomic) NSArray *myArray;

@end

Then in viewDidLoad I would assign it a value, and I will be able to access it throughout the .m file.

My question is: How can I create the same thing (a global private variable) in an NSObject class, which doesn't have @interface and viewDidLoad?

Update

I'm trying to add objects in an array, and use it throughout my NSObject class. Instead of creating it in every method that I'm using it in.

Example:

NSArray *myArray = [[NSArray alloc] initWithObjects: @"One", @"Two", nil];

- (void)firstMethod {
    NSLog(@"%@", [self.myArray firstObject]);
}

- (void)secondMethod {
    NSLog(@"%@", [self.myArray lastObject]);
}

Update 2

When you create a new file with a subclass of NSObject, the .m file doesn't come with @interface myObjectClass () ... @end. Therefore, I don't know where to create my variables that I want to access throughout the myObjectClass.m file.

Hudson
  • 21
  • 3
  • You use term "private global variable", but "global" has a very specific meaning, which I'm inferring you didn't really mean here. Also, your original example is a singleton, but I assume you are not really asking about singletons, but rather classes in general. Is that correct? – Rob May 01 '15 at 12:42
  • @Hudson i think learn some basic first and then come with standard issue, all will glad to help ! as in my answer i defined everything ! – Buntylm May 01 '15 at 13:42

3 Answers3

1

You say:

When you create a new file with a subclass of NSObject, the .m file doesn't come with @interface myObjectClass () ... @end. Therefore, I don't know where to create my variables that I want to access throughout the myObjectClass.m file.

That's true, but there's nothing to stop you from adding this (called a "private class extension") yourself. In fact, that precisely what you should do. Then, all of your private class properties should go inside this private class extension.

See Class Extensions Extend the Internal Implementation.


Going back to your example, you might end up with a public interface defined in MyClass.h that looks like:

@interface MyClass : NSObject

+ (MyClass *)sharedInstance;

- (void)firstMethod;
- (void)secondMethod;

@end

The .m file might include a private class extension which defines the private properties:

@interface MyClass ()

@property (nonatomic, strong) NSArray *myArray;

@end

@implementation MyClass

+ (MyClass *)sharedInstance {
    static MyClass *sharedInstance;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

- (MyClass *)init {
    self = [super init];
    if (self) {
        self.myArray = @[@"one", @"two"];
    }
    return self;
}

- (void)firstMethod {
    NSLog(@"%@", [self.myArray firstObject]);
}

- (void)secondMethod {
    NSLog(@"%@", [self.myArray lastObject]);
}

@end

Bottom line, the class extension may not be added automatically for you, but you can add it yourself.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thank you very much!!! You explained everything really good!! I just have 1 question. When I call `firstMethod` in another class, do do like this: "`[[MyClass sharedInstance] firstMethod]`" Or like this: "'[[MyClass init] firstMethod]`"? (Notice: the `sharedInstance` or `init`) – Hudson May 01 '15 at 18:40
  • @Hudson Your `MyClass` example was a singleton (i.e. a object for which there is one and only one instance which you can use anywhere) which means you probably wanted `[[MyClass sharedInstance] firstMethod]`. The `[MyClass init] firstMethod]` would create a new instance, which is unlikely what you intended. But I'd step back and ask what is this `MyClass` class. Should it be a singleton at all? Singleton's are a special tool used in special cases (and have limitations and problems), so use them sparingly, but where you need them, always used the `sharedInstance` pattern. – Rob May 01 '15 at 19:00
  • If I do [[MyClass sharedInstance] firstMethod] will `myArray` have it's objects? (Would my array have `@"one", @"two"`) – Hudson May 01 '15 at 19:38
  • Absolutely, because `sharedInstance` ends up calling `init`, which sets `myArray`. But the key is that you can call `sharedInstance` many times from anywhere in your code, and the `MyClass` will be instantiated only once because you're dealing with only one shared instance (because it's a singleton). – Rob May 01 '15 at 19:40
  • 1
    Thank you very much!! You were very helpful!! You were patient and explained everything until I completely understood it!! – Hudson May 01 '15 at 19:53
0

for that you define MyClass object out side of sharedInstance method.

static MyClass *sharedInstance = nil;  
+ (MyClass *)sharedInstance
{
             static dispatch_once_t once;
             dispatch_once(&once, ^{
                    sharedInstance = [[self alloc] init];
              });

              return sharedInstance;
}

----------Edited---------

Option 1 - MyViewControllerClassName.m

    @interface MyViewControllerClassName ()
    {
    @private // << note: protected is the default when declared in this scope.
       NSArray *myArray;
    }
    @end

Option 2 - MyViewControllerClassName.h

@interface MyViewControllerClassName : NSObject
{
@private // << note: protected is the default when declared in this scope.
   NSArray * myArray;
}
@end

Option 3 - MyViewControllerClassName.m

@implementation MyViewControllerClassName
{
@private // << note: private is the default when declared in this scope.
   NSArray * myArray;
}

@end

For more reference:Class variables explained comparing Objective-C and C++ approaches

Nimit Parekh
  • 16,776
  • 8
  • 50
  • 72
  • But how can I create an `NSArray`? – Hudson May 01 '15 at 03:52
  • Is that in the .h or .m file? – Hudson May 01 '15 at 04:00
  • Where can I assign the array, so that it will be assigned before other methods get called? (Example, in a `viewController` class, it would be in `viewDidLoad`. But `NSObject` classes doesn't have `viewDidLoad`.) What's the equivalent of `viewDidLoad` in a `NSObject` class? – Hudson May 01 '15 at 04:18
0

I think this is what you want to implement with your NSObject class.

Any concern warm welcome

enter image description here

enter image description here

enter image description here

Buntylm
  • 7,345
  • 1
  • 31
  • 51
  • I just brought the `ViewController` class as an example. I don't wanna access the objects from there. I want to declare, assign, and use an `array` in the `NSObject.m` class – Hudson May 01 '15 at 04:25
  • yes as i also have an `NSObject` class where i can access the `privateObject` with in the class only – Buntylm May 01 '15 at 04:28
  • What method is equivalent to `viewDidLoad` in the `NSObject` class? – Hudson May 01 '15 at 04:31
  • Whats the diff between init and shared...? – Hudson May 01 '15 at 04:42
  • `init` Implemented by any subclasses to initialize a new object so in that case it will return an new object vs `sharedInstance` as above is an developer defined function that will return the same object again and again (used for following the singleton design parttern) – Buntylm May 01 '15 at 04:43
  • I will be using singleton. How can I add the `_privateObjec...` in "sharedInstance` – Hudson May 01 '15 at 04:46
  • access the privateObject what return object in shareInstance `sharedInstance.privateObject = @"setvalue"; return sharedInstance;` – Buntylm May 01 '15 at 04:53
  • Sorry for driving you crazy!! I'm a beginner. First: can I remove `+ (MyClass *)sharedInstance` if I have `(instancetype)init`? Second: the way I access method, (`firstMethod') (calling a method from myClass to another class) would be like this: `[myClass init] firstMethod]`? – Hudson May 01 '15 at 05:03
  • And, does `init` get called before all other methods? – Hudson May 01 '15 at 05:07
  • 1
    FWIW, while I appreciate the commendable intent of this answer, the examples are problematic: 1. The use of manually defined ivars and `@synthesize` statements is no longer common practice. 2. He's using ARC, so `strong` should be used in lieu of `retain`. 3. The declaration of that `readonly` property is missing any memory semantics (meaning that it's `assign`), which is unlikely what you intended. You also shouldn't just include code samples, but explain what the intent of each was. Finally, I'd suggest the use of code blocks rather than image snapshots in the future. – Rob May 01 '15 at 18:02
  • Thanks for this valuable comment ! – Buntylm May 02 '15 at 03:58