关于iPhone上的ivars和@ property的问题

时间:2010-01-31 22:03:37

标签: iphone objective-c cocoa

我有一个关于实例变量如何工作以及何时使用@property的问题。这是我正在使用的示例界面文件

@interface PackageModel : NSObject {
    NSString *tracking;
    NSString *carrier;
    NSString *status;
    NSMutableDictionary *events;

    // Connection ivars
    NSMutableData *receivedData;

    // Parsing ivars
    int tagLevel;
    NSMutableArray *tagTree;
    NSString *parentTag;
    NSString *currentTag;
}

@property (nonatomic, retain) NSMutableData *receivedData;

- (id)initWithTrackingString:(NSString *)string;
- (void)getPackageDataWithEvents;
- (void)printMe;

@end

如何在文件代码中访问这些内容。我可以通过使用类似

之类的东西来访问此类方法中的跟踪,载体和状态
tracking = [[NSString alloc] initWithString:@"Hello World"];

此外,dealloc中需要放置哪些变量?只有我在@ property / @ synthesize中的变量?或者我是否需要在dealloc方法中释放所有实例变量。

我正在寻找关于实例变量如何在Objective-C中工作的一些说明。感谢。

4 个答案:

答案 0 :(得分:3)

@property声明只不过是编译器生成的getter和setter方法。而已。只是方法。显然,你必须得到并设置某些东西,所以我们创建了与getter和setter一起的ivar。在上面的示例中,您的编译器正在生成:

- (NSMutableData *) receivedData;
- (void) setReceivedData:(NSMutableData *)newReceivedData;

getter返回receivedData实例变量中的值,setter更改receivedData实例变量中的值。

(旁注:使用64位运行时,您可以跳过声明实例变量,但我仍然希望将其置于显式中)

至于您应该在dealloc方法中执行的操作,您需要释放已经retaincopy编辑的实例变量。因此,在您的示例中,您需要在[receivedData release];方法中执行dealloc,因为当您设置receivedData ivar时,您保留了新值(这就是retain }表示@property行。如果您未在retain声明中指定copy@property,则默认为assign,您无需执行任何操作。除此之外,您还需要释放自己保留的任何其他实例变量(即,不通过@property (retain) setter)。

对于你的上一个问题,是的,你可以这样做:

tracking = [[NSString alloc] initWithFormat:@"Hello, %@!", @"world"];

在您自己的类中,您可以直接访问所有自己的实例变量(以及超类的任何受保护和公共ivars)。

答案 1 :(得分:1)

Yikes,这是一个非常广泛的问题。我强烈建议您阅读Apple的Objective-C Primer及其full reference to the language

作为首发,您会问:“如何在文件代码中访问这些内容?”您没有指定哪个文件。在@implementation的{​​{1}}内,您可以像跟踪示例中那样简单地引用实例变量。您无法从其他课程轻松访问它们。

但是,如果您将它们设为PackageModel@properties,则可以在类本身内访问它们,例如@synthesize。此外,您现在也可以从其他类访问它们。

self.tracking

这些属性的另一个优点是它们可以为您处理内存管理。如果操作正确,您真的不需要担心保留和释放。 PackageModel *model = [[PackageModel alloc] init]; model.receivedData = [NSMutableData data]; 类上的receivedData属性将在分配新数据之前自动释放任何先前保留的对象。这是光荣的。发生这种情况是因为编译器会自动“合成”setter和getter,然后通过点运算符调用它们进行访问。

最后要注意的是,这些setter和getter会被PackageModel块自动保护,以确保操作以原子方式发生(并且第二个线程无法在中途中断活动)。这在iPhone上很大程度上是不必要的并且会导致相当大的开销,因此除了您的读/写权限和内存管理方案之外,您还应该将所有属性声明为@synchronize

答案 2 :(得分:1)

未涵盖的是您的最后一行代码可能是:

tracking = @"Hello World";

“@”基本上是为你创建字符串对象。

答案 3 :(得分:0)

使用@ property / @ syntehsize的一个好处是它会促使您使用ivars的访问器方法。这有助于您更好地管理内存。在iPhone上,让您了解保留计数有两个重要原因:1。保持内存使用率下降。 2.避免崩溃。当您直接访问ivars时,您可能会忘记保留变量,然后稍后访问它以发现它已被释放。或者恰恰相反,你忘了发布一个变量,很快你就已经积累了大量的内存,以至于iPhone OS告诉你的应用程序要终止。

使用访问器方法,即使在课堂内,通常也是一个好主意。我通常直接设置ivars的唯一地方是在类的init方法中。我通常也会在dealloc方法中释放所有我的ivars。