2013-02-09 161 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; 

希望这有助于(并回答你的问题,如果没有的话可以将其作为参考为希望了解更多有关属性和实例变量人)