首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@property retain iPhone

@property retain iPhone
EN

Stack Overflow用户
提问于 2011-01-14 14:29:59
回答 3查看 1.4K关注 0票数 3

我是iPhone编程的新手。我有以下疑问,这阻碍了我继续前进。请考虑以下代码:

代码语言:javascript
复制
---------.h------
@interface myClass: UIViewController
{
    UIImage *temp;
}

@property (nonatomic, retain) UIImage *temp;

 ---------.m------
 @interface myClass
 @synthesize temp;

 -(void) dealloc
 {
   [temp release];
   [super dealloc];
 } 
  1. 以上是唯一的程序代码。就这样..。没别的事了。我是否需要在dealloc方法中声明临时发布,即使我在程序中根本没有使用属性访问器方法。如果我没有在dealloc中宣布临时释放怎么办。这会造成内存泄漏吗?因为我没有调用属性访问器方法,所以我发布了一些我没有保留的内容。
  2. 另外,当我打印时,为什么它显示为0,即使它被保留在@property中。

提前感谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-14 14:38:42

你所做的是正确的。滚动到Apple:声明属性的"dealloc“部分

然而,不久,当您合成这些属性(在下一次可可更新中)时,这些属性将被自动清除--尽管如此,我个人已经开始遵循的惯例是,我的代码在未来的工作中将self.temp = nil;设置为dealloc,而不是发送发布消息(请阅读我发布的苹果文档,它解释了这一点)。在运行时创建的访问器方法首先释放对象,因此对于我和许多其他开发人员来说,这是清理dealloc中声明的属性的更好/更安全的方法。

票数 0
EN

Stack Overflow用户

发布于 2011-01-14 14:39:32

  1. 如果没有为( myClass.temp的一个实例)分配任何值,那么就不会有泄漏。但是您应该在您的dealloc中发布
  2. @property只是myClass实例将具有此属性的声明。在保留该值之前,需要为其赋值。 myClass *myClass= [myClass alloc init];//实例现在将保留传递给//的值,因此负责释放它-- instance.temp = UIImage imageNamed:@“任何”;/如果实例不在其他任何地方保留,//它的dealloc将称为实例释放;

在侧面,您应该给出以大写字母(即MyClass )开头的类名。不需要,但能让事情更清楚。

您也可以在您的dealloc中使用您不认为的dealloc,但是它工作得更好,看起来更干净。这是个模棱两可的话题。

票数 1
EN

Stack Overflow用户

发布于 2011-01-20 07:46:21

你的代码是正确的。

一般规则是,对于@interface中声明的所有变量,必须在-dealloc中清除它们。根据声明@属性的方式,需要释放一些变量,而其他变量则只需为零。

在上面的示例中,temp可能从来没有被您显式地赋予一个值,但是当您的类的一个实例被分配时,ObjC运行时会将temp的值初始化为零。

向nil对象发送-release通常不是一个问题,因此‘tempRelationsis fine. It's a no-op. When _temp_ has a non-nil value in-dealloc,the [temp发布’可以完成释放内存的工作。

如果在创建时需要临时的非零值,则需要实现-init方法并确保它得到一些值。虽然您的类是合法的&没有-init方法的函数式,但是您确实应该养成在您设计的每个自定义类中都包含一个的习惯。

您至少需要默认的初始化器:-init。您还可能希望设计一个更详细的初始化器,它可以用于为您的temp提供一个值,如-initWithImage:

以下是你在课堂上应该包括的内容:

代码语言:javascript
复制
@implementation MyClass

...

- (id) init {
   self = [super init];
   if (self != nil) {
      // The minimal default initializer.
      // temp will already have a value of nil, so you don't need necessarily 
      // need to do anything more, unless temp needs a real value on initialization.
   }
   return self;
}

- (void) dealloc {
...
}

@end

若要实现更详细的初始化程序(也称为指定的初始化程序),请执行以下操作:

代码语言:javascript
复制
@implementation MyClass

...

- (id) initWithImage:(UIImage *)newImage {
   self = [super init];
   if (self != nil) {
      temp = [newImage retain];
   }
   return self;
}

// Implement the default initializer using your more detailed initializer.

- (id) init {
   // In this default initializer, every new instance comes with a temp image!
   return [self initWithImage:[UIImage imageNamed:@"foobar"]];
}

- (void) dealloc {
...
}
@end

在这里,指定的初始化器-initWithImage:是权威的初始化器。所有其他初始化器,包括-init,都是使用-initWithImage:实现的。

您可以在是否实现最小默认初始化项之外的任何初始化器上行使大量的酌处权。也许-init对您的目的来说已经足够好了。这很好。有时,更详细的初始化器会使类的使用更加方便。经验(和原力)将是你的指南。

注意,我没有在任何初始化器方法中使用生成的属性访问器。如果情况不需要,则通常应该避免在-init方法和-dealloc中使用属性访问器,这主要是因为潜在的无法解决的问题,以及自动键值编码通知的副作用。

初始化器和dealloc方法在类中扮演特殊角色。作为类设计器,在这些方法中设置和清理实例变量是您的责任。一个很好的经验法则是为类的调用者保留合成属性访问器的使用,以及类中其他方法的实现。

当对实例进行初始化或取消分配时,您可以并且应该直接接触ivars。他们是你的了。你宣布了他们,所以你可以直接处理他们。在实现类中的其他方法时,通常应该使用属性访问器。

JeremyP与Cocoa对象概念文档的链接是一个很好的链接。您应该明确地阅读有关对象的部分,并定期重新阅读它,因为您获得了更多自己编写自定义类的经验。最终,这一切都会变得有意义。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4692079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档