2013-02-09 89 views
1

我在我的Cocoa項目(Xcode)中有2個類。首先是AppDelegate類,第二個是Book類。從類或方法訪問對象

在我的Book類中,我在@interface中設置了一個整數屬性,這是本書的章節。在它的@implementation中,我創建了對象(例如Book * firstBook = [[Book alloc] init])並設置它們的屬性(在Book.m文件中)。這些是我的數據,不會改變。

在我的應用程序委託中,我有一個方法可以獲取用戶從界面項目中選擇的內容,獲取所選項目的標題,誰的名字將與Book.m中的相同。然後,for循環將運行以創建popUpButton的菜單項,以便用戶可以選擇要跳轉到的章節。

我現在看到的問題是,當我嘗試運行for循環創建菜單項時,我需要循環的限制量。該限制量基於selectedObjectByUser的章節屬性(在Book.m中列出)。我如何訪問它。

如果我可以將這兩者連接在一起,因爲它在此方法(AppDelegate.h下)內創建對象時有效,但問題在於它太耗費空間並且經常更改,所以我相信它會起作用。

回答

3

我不完全確定這裏的情況,但讓我們先看看一些示例代碼。

//// 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 

所以在這方面我們建立一個類,併爲它提供3個屬性,標題和作者(這兩者都是的NSString的)和numberOfPages(這是一個整數)。在課堂上,我們可以通過調用諸如self.propertyName = value之類的東西來操縱這些值。

這一切都很好,但究竟發生了什麼?那麼讓我們來更新頭多一點:

//// 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 

在這方面,我們剛剛明確定義的東西,編譯器通常會通過@property結構推斷。這些新增功能是我們所稱的實例變量或ivars,並且是您分配給您的屬性的值實際存儲的位置。

但是,如果你還沒有100%的內存管理舒適度,操縱ivars可能是危險的。即使你使用的是ARC,你仍然應該理解這個管理是如何工作的。

所以我們現在公開了這些屬性實際存儲數據的位置,但那@private工作呢?這是關於什麼的? @private是幫助表示某些內容的「可訪問範圍」的關鍵字家族的一部分。這個家族中的另外兩個關鍵詞是@protected@public,但是如果不是不尋常的話,那麼使用第二個關鍵詞的頻率就很少。這些關鍵字負責說明你被允許訪問的地方。這是他們的一個快速定義。

  • @public從任何地方可自由訪問,外連對象本身。然而直接從它自己的類之外訪問一個實例變量在Cocoa開發世界中通常被認爲是非常糟糕的做法,因此爲什麼你很少會發現如何去做。

  • @protected在班級及其自己的子類中可以自由訪問。無法在類/對象之外訪問。

  • @private在課堂上自由訪問,但不在其他地方。不能在類/對象之外甚至其子類之外訪問。

所以,現在,我們已經介紹了什麼是真正駕駛特性背後的存儲,讓我們來看看使用我們Book對象在應用程序的其他部分,如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 

在此,我們創建一個新的Book對象,把它更多的技術術語,我們定義了一個名爲myBook變量和類型的Book並創建實例。在這裏,我們使用前面創建的-initWithTitle:andAuthor:方法來告訴Book對象它應該有一個初始標題和作者。

按照這條線,我們會得到一些更好奇的東西。 myBook.title = @"My Cool Book";您可能還記得我們在Book.m,self.title = aTitle有類似的東西。那麼這裏發生了什麼?爲什麼我們現在使用myBook而不是像我們以前那樣使用myBook?原因是因爲實際上是什麼。

self是由Objective-C運行時提供的一個關鍵字,它引用了您所在的當前對象。所以如果我們在Book.m中編寫代碼,self會引用當前的Book對象。如果我們在AppDelegate.m中使用self,它將引用AppDelegate。因此,在我們之前的代碼中,self指的是當前的Book對象,就像我們的myBook對象現在引用特定的Book對象。它們本質上是相等的(不完全相同,但這是另一個討論區域)。

這意味着Book或方法中的任何屬性都可以通過myBook變量訪問,就像在Book.m中使用self一樣。所以,我們也可以做

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

希望這有助於(並回答你的問題,如果沒有的話可以將其作爲參考爲希望瞭解更多有關屬性和實例變量人)