iPhone实例variables问题

我想弄清楚合成myString到实例variables_myString的目的是什么。

这样做的目的是什么? 我倾向于注意到很多人这样做。

另外我应该释放实例variables,并将实例variables设置为零,这是正确的。

ViewController.h

#import <UIKit/UIKit.h> @interface ViewController : UIViewController { NSString *_myString; } @property (nonatomic, retain) NSString *myString; @end 

ViewController.m

 #import "ViewController.h" @implementation ViewController @synthesize myString = _myString; - (void)viewDidLoad { [super viewDidLoad]; self.myString = [[NSString alloc] initWithFormat:@"Hello"]; _myString = [[NSString alloc] initWithFormat:@"Goodbye"]; NSLog(@"%@\t%@", self.myString, _myString); } - (void)viewDidUnload { _myString = nil; [super viewDidUnload]; } - (void)dealloc { [_myString release]; [super dealloc]; } @end 

当您在目标c中合成对象types属性时,编译器将为该实例variables生成两个隐藏方法。 因此,当您引用myObject.myString ,不仅会返回_myString的指针,而且还会调用生成的- (NSString*) myString方法。 同样的,如果你给这个属性赋值: myObject.myString = @"foo"; 它将被编译为[myObject setMyString:@"foo"];

什么是- (NSString*) myString- (void) setMyString:(NSString*) theString依赖于您在声明属性时指定的关键字。 最常见的就是assign这个简单的指定你给的指针:

 - (void) setMyString:(NSString*) theString { _myString = theString; } - (NSString*) myString { return _myString; } 

这与声明_myString一个公共variables没有太大的区别,但是更直接地说这个variables可以直接从外部访问。

反过来, retain生成类似的setter方法(getter方法将是相同的):

 - (void) setMyString:(NSString*) theString { [theString retain]; [_myString release]; _myString = theString; } 

您可以看到,这照顾了您传递给该属性的对象的内存pipe理。 换句话说,你可以确定这个对象在你拥有它之前不会被释放,所以当你拥有它的时候,你不必手动retain它。 这使编写pipe理内存的代码更加方便而不会泄漏。 请注意,在dealloc中,您仍然需要将nil应用于您的属性才能释放其存储的最后一个对象。

数据不是来自实例variables,而是来自其他数据源(如数据库)的另一类属性。 核心数据的pipe理对象的自动生成的属性,例如工作。

最后,你也可以定义你自己的getter和setter。 例如,围绕一些常用的NSUserDefaults设置编写一个属性包装,这将有助于它的访问:

 @interface Bar @property (nonatomic, assign) NSString* foo; @end @implementation Bar - (void) setFoo:(NSString *)theFoo { [[NSUserDefaults standardUserDefaults] setObject:theFoo forKey:@"settings.foo"]; } - (NSString*) foo { return [[NSUserDefaults standardUserDefaults] stringForKey:@"settings.foo"]; } @end myBar.foo = @"foobar"; // automatically persisted between application runs 

还请阅读这些内容: 目标C中的 高级内存pipe理和声明的属性

self.myString(技术上[self myString])实际上是通过这个对象中的函数访问和设置ivar _myString,如下所示:

 -(NSString *)myString { // code that is automatically generated by the @synthesize statement OR // code that you write which over-rides the generated accessor. // both of which generally return the value stored in _myString } -(void)setMyString:(NSString *)newString{ // code that generally changes the value of _myString } 

使用_myString直接绕过这些函数并直接访问伊娃。

人们倾向于合成属性来强调前缀variables,而不是在编写其他代码时误认这两个variables。 例如:

 // ... do sth myString = @"Foo"; // ... do sth else ... self.myString = @"Bar"; 

第一条指令直接访问variables,第二条指令使用合成的setter。 在不指向特定variables的情况下进行合成时,将为您创build与该属性同名的variables:

 @synghesize myString; // this creates myString variable for you 

而不是这样做,人们创build下划线前缀variables,以避免直接错误地访问它。 当他们这样做的时候,第一条指令myString = @"Foo"不再编译,这样就可以很容易地避免错误的绕过getter或setter时的错误。

至于你的第二个问题,如果可能的话使用ARC。 如果没有,你应该首先释放variables,然后重置指针。 在你提交的代码中,viewDidUnload将比dealloc调用的早,所以你将会有一个内存泄漏,因为_myString会在调用release之前指向nil。

它被声明为区分对象内的私有variables和公共variables。 这是一个完全可选的。

看到这个: 什么时候UIViewController的viewDidUnload被调用? 和我在viewDidUnload中究竟做了什么? 。

它可能会帮助你。