Why use pointers in BNRItem?


#1

I’m just reading through the part on defining the BNRItem class and specifying it’s instance variables. Why are itemName, serialNumber and dateCreated created as objects outside of BNRItem and defined using pointers whereas valueInDollars is stored as an int within BNRItem itself? Why not store the others as NSStrings and NSDates within BNRItem?

The code I’m referring to is:

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
NSString *_itemName;
NSString *_serialNumber;
int _valueInDollars;
NSDate *_dateCreated;
}
@end

Why can’t we say:

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
NSString _itemName;
NSString _serialNumber;
int _valueInDollars;
NSDate _dateCreated;
}
@end

#2

It looks like you have jumped right in, without first reading BNR’s Objective-C book.

[quote]Why are itemName, serialNumber and dateCreated created as objects outside of BNRItem and defined using pointers whereas valueInDollars is stored as an int within BNRItem itself? Why not store the others as NSStrings and NSDates within BNRItem?
[/quote]
That’s Objective-C’s way of indicating that valueInDollars is the name of a value-type object, and _itemName, _serialNumber, and _dateCreated are the names of reference-type objects.

You can think of the name of a value-type object as directly representing the value of the object itself, and of the name of a reference-type object as representing, not the value of the object itself, but its address.

[Become a competent programmer faster than you can imagine: pretty-function.org]


#3

Thank you ibex10. You’re right, I have not read their Obj-C book…maybe I should.

I think I understand what you’re getting at, but why is this way better than keeping the objects within BNRItem itself?

Edit:------------

OK, so I’ve read the relevant section in BNR’s Objective-C book and I can understand the logic behind declaring ivars as pointers to other objects in complex situations. However, in this situation, with something as simple as a string or date, why bother with this method?


#4

Might I suggest rereading the relevant section? :slight_smile:

For starters, recall that Objective-C is built on top of C. So anything that’s not a primitive type in C must be either a structure or a pointer. Some parts of Cocoa, like Core Graphics, make extensive use of structures. But for the most part, if it’s not a primitive, it’s going to be a pointer.

Here’s a thought experiment: If you’re the computer, and I tell you I need enough memory to store a string, how much memory are you going to allocate (without being excessively wasteful)?

The answer is: you have no idea without my telling you what I want to store in that string! The point is, the amount of memory for a string is not constant. And since that space is not constant, it means you’re going to have to allocate that memory at runtime. And that means you’re going to end up with a pointer. (See the documentation for malloc(3).)

For things like strings and dates, we don’t get to decide whether to use a pointer or not; it must be that way if we want it to work.


#5

Thanks gc3182. I’ve done a little more reading and I think I understand the requirement for it, now.

However;

I understand you don’t know the length of a string before that string is created, but a date? Obviously you won’t know its value beforehand, but surely all dates are of the same length? dd/mm/yyyy hh:mm:ss:msms ?


#6

If we wanted, we could write our own code for strings and dates, and that would be a really good educational exercise.

However, NSDate and NSString classes already exist. Why not use them? And that’s what the example in the book is doing: showing how to use existing resources.

As far as writing our own string and date is concerned, NSString is relatively simple to write; it is just a sequence of unicode characters. But NSDate is not so easy: we need to figure out how to convert the clock ticks since a reference time in the past to meaningful information, which is not a trivial task (clock ticks is maintained by OS and hardware.) We might as well make use of the tested code others have written.


#7

I think it’s all just clicked into place - you can’t have an object inside an object, right!?


#8

Of course, you can!

For example:

  • The drawer next to my desk contains several objects: an iphone, an old mac mini, a battery charger, and several batteries.
  • You can put an array object inside another array object:
NSArray * foos = GetFoos ();
NSArray * bars = GetBars ();
NSArray * foosAndBars = [NSArray arrayWithObjects:foos, bars, nil];