user1927992
user1927992

Reputation: 123

Accessing Objects from Class or Method

I have 2 classes in my Cocoa project (Xcode). First is AppDelegate class and the second is a Book class.

In my Book class, I set an integer property in the @interface which is the book's chapters. In its @implementation, I have created objects (ex. Book *firstBook = [[Book alloc]init]) and set their properties (In the Book.m file). Those are my data and will not change.

In my app delegate, I have a method that will fetch what the user selected from an interface item, get the title of the selected item, who's name will be identical to one of those in Book.m. Then a for loop will run to create menu items for a popUpButton so the user can select which chapter to jump to.

The problem I am seeing now is that when I try running the for loop to create menu items, I need the limit amount of the loops. That limit amount is based on the selectedObjectByUser's chapter property (listed in Book.m). How do I access that.

I am sure it will work if I can connect these two together because it works when create the object inside this method(under AppDelegate.h) but the problem is that it is too space consuming and it changes often.

Upvotes: 1

Views: 155

Answers (1)

Tom Hancocks
Tom Hancocks

Reputation: 440

I'm not entirely sure what the situation is here, but let's take a look at some sample code first.

//// Book.h
@interface Book : NSObject

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;

@end


//// Book.m
@implementation Book

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor {
    if ( self = [super init] ) {
        self.title = aTitle;
        self.author = anAuthor;
    }
    return self;
}

- (void)dealloc {
    self.title = nil;
    self.author = nil;
    [super dealloc];
}

@end

So in this we establish a class and provide it with 3 properties, title and author (which are both NSString's) and numberOfPages (which is an integer). Within the class we can manipulate those values by calling things such as self.propertyName = value.

This is all well and good, but what actually is happening? Well let's update the header a little more:

//// Book.h
@interface Book : NSObject {
@private
    NSString *_title;
    NSString *_author;
    NSInteger _numberOfPages;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;

@end

In this, we have just explicitly defined something that the compiler will normally infer through the @property construct. These new additions are what we call instance variables, or ivars, and are where the values you assign to your properties are actually stored.

However, manipulating the ivars can be dangerous if you are not yet 100% comfortable with memory management. Even if you are using ARC, you should still understand how that management works.

So we've now exposed where these properties actually store there data, but what about that @private job? What's it all about? @private is part of a family of keywords that help to denote the "Accessibility Scope" of something. The other two keywords in this family are @protected and @public, however the use of the second two is infrequent, if not unusual. These keywords are responsible for saying where you are allowed to access things. Here's a quick definition of them.

  • @public Freely accessible from anywhere, even outside of the object itself. However accessing an instance variable directly from outside of its own class is generally considered to be extremely bad practice in the Cocoa development world, hence why you'll find very little on how to do it.

  • @protected Freely accessible within the class and its own subclasses. Can not be accessed outside of the class/object.

  • @private Freely accessible within the class, but not anywhere else. Can not be accessed outside of the class/object or even in its subclasses.

So now that we've covered what is actually driving the storage behind a property, let's take a look at using our Book object in another part of the app, such as AppDelegate.

//// AppDelegate.m
@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    Book *myBook = [[Book alloc] initWithTitle:@"pending title" andAuthor:@"Foo Bar"];

    myBook.title = @"My Cool Book";

    NSLog(@"%@ by %@", myBook.title, myBook.author);

    [myBook release];
}

@end

In this we create a new Book object, to put it in more technical terms, we define a variable called myBook with a type of Book and instantiate it. In this we're using the -initWithTitle:andAuthor: method that we created earlier in order to tell the Book object that it should have an initial title and author.

Following this line we then arrive something a little more curious. myBook.title = @"My Cool Book"; You might recall that we had something similar back in Book.m, self.title = aTitle. So what is going on here? Why are we using myBook now rather than self, like we did previously? The reason is because of what self actually is.

self is a keyword provided by the Objective-C runtime, and refers to the current object that you are within. So if we write code inside Book.m, self will refer to the current Book object. If we use self within AppDelegate.m, it will refer to the AppDelegate. So in our earlier code, self was referring to the current Book object much like our myBook object is now referring to a specific Book object. They essentially are equal to each other (not exactly, but thats another area of discussion).

This means any of the properties within Book or methods can be accessed through the myBook variable, much like you would using self inside of Book.m. So we could also do

myBook.title = @"My Book";
myBook.author = @"Baz Quux";
myBook.numberOfPages = 100;

Hope this helps (and answered your question, if not then may it serve as a reference to people wishing to know more about properties and instance variables)

Upvotes: 3

Related Questions