0

I'm making a program using Objective-C (Xcode) and I need to be able to make an instance of another class.

- (void)viewDidLoad {
    [super viewDidLoad];
    currentSide = 0;
    [self loadStage];
    Cube *cube = [[Cube alloc] init];
}

I wanted to make an instance of Cube as soon as the first Viewcontroller loads, but when I make it there, no other methods can access it.

I'm brand new to Obj-C but as I understand it, Viewcontroller.m should not have a main method in it, as this is in the main.m file. So where should class instances be made?

I bet I'm missing something obvious. Thanks in advance.

Gavin
  • 8,204
  • 3
  • 32
  • 42

4 Answers4

2

If you just want a simple ivar, instead of a property, you simply want to define it in your @implementation { ... }.

There's simply no need for it to be in the @interface as this exposes your class's inner workings to other classes. See this amazingly detailed answer for more info.

Example of ivar usage:

@implementation YourViewController {
    Cube *cube;
}

You can then load this in from your viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    currentSide = 0;
    [self loadStage];
    cube = [[Cube alloc] init];
}

And can freely access it throughout your class:

-(void) foo {
    cube.bar = @"baz";
}

I prefer ivars over properties for something like this (internal variables) for a few reasons:

  • If you aren't using any getters or setters, why overlay an extra layer over the ivar if you're not going to use it? (that's all properties are at the end of the day).

  • They're much cleaner to use in your class (cube instead of self.cube).

  • They're much quicker to define.

  • They're much easier to distinguish from external properties (I like to keep external values and internal values separated).

  • They're faster. Okay, only by a couple of nanoseconds, but every little counts.

Although, it's worth noting that properties are better than ivars (for internal storage) in some situations:

  • If you want to make your code thread safe, you should be using atomic properties in order to ensure that read & writes are serialised correctly.

  • If you want to use internal getters and setters (I have never needed to do this, but it's there if you want).

  • If you want to use KVO (although, again I've never needed to this internally).

At the end of the day, it's still a matter of preference. I am aware that I was maybe a little too sledge-hammer-y in asserting that ivars are better than properties in some of the comments I made.

Community
  • 1
  • 1
Hamish
  • 78,605
  • 19
  • 187
  • 280
2

I would do it like this, in your .m file:

  @interface YourClass () 

  @property(nonatomic, strong) Cube cube;

  @end

  @implementation YourClass

  - (void)viewDidLoad {
    [super viewDidLoad];
    currentSide = 0;
    [self loadStage];
    self.cube = [[Cube alloc] init];
  }

  @end

You don't have to use the @property syntax, but it's the standard convention, makes your code easier to read, allows you to have a getter or setter later if you so need it, and easily allows you to specify how ARC should treat the object.

i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
1

you can do a lazy initialization.

Declare Cube first as a class property variable. (in your .m file)

@property Cube *cube;

then override the getter method of cube like this

- (Cube *)cube
{
   if(!_cube) {
      _cube = [[Cube alloc] init];
   }
   return _cube;
}

then to use the object in any method of your class

[self.cube anyMethodOfCube];
dizzyboy
  • 370
  • 6
  • 19
  • 1
    seems excessive. No other class needs to see it from what I can see, so no need for it be a property, OP just wants it to be accessible from any method in his class. It should be an ivar in the `@implementation` (do I really have to make my own answer?). – Hamish Feb 03 '16 at 21:43
  • 2
    You can declare the `@property` in your .m file, then it will only be visible to the class. – i_am_jorf Feb 03 '16 at 21:44
  • @i_am_jorf but that's still excessive. OP has no need for getters and setters, he just wants a simple ivar. – Hamish Feb 03 '16 at 21:45
  • @i_am_jorf yup forgot to add that – dizzyboy Feb 03 '16 at 21:45
  • @originaluser2 sounds like you want to provide another answer that isn't seen here. – i_am_jorf Feb 03 '16 at 21:47
0

define your object in interface as:

@implementation YourViewController
{
  Cube *cube;
}

and initialize in first use or directly in viewDidLoad:

cube = [[Cube alloc] init];

-(void)someOtherMethodInViewController
{
      [cube cubeMethod];//now it is reachable
}

EDIT as originaluser2 stated in comment, there is a detailed explanation for the case. but for improving the answer i changed according to that link.

meth
  • 1,887
  • 2
  • 18
  • 33
  • 3
    why in the `@interface`? no other class needs to see it. I'd do it in the `@implementation { ... }` (http://stackoverflow.com/questions/13566862/where-to-put-ivars-in-modern-objective-c) – Hamish Feb 03 '16 at 21:36
  • @Adam it's bad practice. No other class needs to see the class's ivars. See http://stackoverflow.com/questions/13566862/where-to-put-ivars-in-modern-objective-c – Hamish Feb 03 '16 at 21:46
  • The OP has made no mention of whether it is required to be private or not. The question just stated that it needs to be accessible by other methods, it made no mention of requiring it to be hidden from other objects. – Adam Jenkins Feb 03 '16 at 21:48
  • 2
    @originaluser2 feel free to add your own answer. It is a little about style and convention and personal approach. Personally I almost never use iVars. Things are either properties in the .h or .m if they are 'private'. This is OOP after all. In fact if you see JoePasq's answer on the question you linked to, this is Apple's recommendation too. – Paulw11 Feb 03 '16 at 21:50
  • 1
    @Paulw11 properties are way too clunky for such a simple task in my opinion, you are indeed right about it being about personal preference though. Maybe I was being a little too blunt in expecting others to conform to my style. – Hamish Feb 03 '16 at 22:09
  • @originaluser2. I think so. Personally I like to be able to look at code and say "that is a method variable" or "that is a property". And don't get me started on people who declare properties and then use `_property` throughout their code – Paulw11 Feb 03 '16 at 22:12
  • @Paulw11 well I like to look at code and easily draw a line between external values and internal values. Using properties for internal variables just blurs the line in my opinion, but each to their own ;) – Hamish Feb 03 '16 at 23:06