Iphone-分配属性和实例变量



嗯,我仍然对目标c属性和实例变量感到困惑。我在视图DidLoad中创建了一个LocationManager对象。一方面,LocationMan只是一个实例变量,另一方面,它被声明为一个属性。看看例子:

第一个例子:

标题:

CLLocationManager* _locationMan;

实施:

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];
_locationMan = theManager;
_locationMan.delegate = self;

第二个例子

标题:

CLLocationManager* _locationMan;
@property (retain, nonatomic) CLLocationManager* locationMan;

实施:

self.locationMan = [[[CLLocationManager alloc] init] autorelease];
self.locationMan.delegate = self;

除了第二个有效和第一个无效之外,这些例子之间有什么区别?内存管理是怎么回事?

您在第一个示例中遇到的问题:

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];

由CCD_ 1的使用引起。autorelease可以看作是:在不久的将来的某个时刻,release自动地将这个对象。给定autorelease的实现方式,通过释放池,这通常发生在控制流下次返回到主循环并且释放池被清空时。

因此,在第一种情况下,您正在创建对象并将其存储在您的ivar中;但很快它就会被释放,而且由于您没有在其他地方明确保留它,它最终会被释放。当你访问它之后,你会得到错误。如果你没有使用autorelease,一切都会正常工作:

CLLocationManager* theManager = [[CLLocationManager alloc] init]; //-- this is correct
_locationMan = theManager;  //-- because you assign directly to the ivar

在第二个例子中,创建是一样的,也就是说,对象也将被标记为自动释放。但是,在这种情况下,您将其指定给一个具有retain修饰符的属性。这意味着在指定给特性时,对象将自动保留。因此,当自动释放真正完成时(大致上,当你回到主视图时),你的对象的保留计数已经增加了1;那么自动释放它将不会使其保留计数变为0,并且不会释放该对象。

你必须清楚地知道:

  1. CCD_ 7将保留计数设置为1;

  2. retain属性在分配给它们时将增加保留计数;

  3. autorelease就像一个延迟发布,因此在发布之前,也就是说在方法和调用程序的其余部分直到主循环中,您可以安全地使用该对象,然后它就会被释放。

我在代码中标记了保留的更改,也许它会变得更清楚。

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];
                                                     ^^^^^ + 1    ^^^^^^^^^^^ - 1 = 0
_locationMan = theManager;

当您的retains drop为0时,该对象就不存在了。下次你尝试访问它时,你的应用程序会崩溃。由于自动释放,这将在您的自动释放池耗尽后发生,在您离开当前方法后的未来未知点。


self.locationMan = [[[CLLocationManager alloc] init] autorelease];
    ^ + 1                               ^^^^^ + 1    ^^^^^^^^^^^ - 1 = +1

您仍然保留了该对象。你必须稍后发布它,但你可以毫无问题地访问它。

在第一个实例中,您没有经过合成的setter,它负责保留对象。在这种情况下,当autorelease0被自动释放时,_locationManager没有抓住任何东西,因此theManager被解除锁定。

第二种情况使用合成的setter(因为它通过self调用它),所以它在自动释放后保留theManager

相关内容

  • 没有找到相关文章

最新更新