首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何保留我自己的对象和属性

如何保留我自己的对象和属性
EN

Stack Overflow用户
提问于 2011-05-15 16:02:24
回答 3查看 130关注 0票数 0

我不确定我是否理解了alloc和retain的工作原理。

最近,我发现NSString属性没有保留,在设置它们时,我必须添加myString副本。这让我想知道我是否误解了保留/分配的整个使用方式

有没有人能告诉我我做得是否正确?我读了很多关于开源项目的书,这让我意识到我可能从一开始就错了。

下面是我的方法:

代码语言:javascript
复制
/**** VIEW.h *****/
#import "MyClass.h"
@interface MyViewController : UIViewController  {
      //Is the following line really necessary?
    MyClass *myObject;
}
@property (nonatomic, retain) MyClass *myObject;
- (void)defineObject;
@end

代码语言:javascript
复制
/**** VIEW.m *****/
#import "VIEW.h"
@implementation MyViewController
@dynamic myObject;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self defineObject];
    NSLog(@"My object's name is: %@", myObject.name);
}

- (void)defineObject
{
      //Here particularly, Why doesn't it work without both alloc and init
      //shouldn't "@property (nonatomic, retain) MyClass *myObject;" have done that already?
    myObject = [[MyClass alloc] initPersonalised];
    [myObject setName:@"my name"];
}

代码语言:javascript
复制
/**** MyClass.h *****/
@interface MyClass : NSObject {
      //not sure if this line is still necessary
    NSString *name;
}

@property (nonatomic, retain) NSString *name;

- (id)initPersonalised;
- (void)setName:(NSString *)name;
- (NSString *)name;

@end

代码语言:javascript
复制
/**** MyClass.m *****/
#import "MyClass.h"
@implementation MyClass

@dynamic name;

(id)initPersonalised{   
    self = [super init];
    name = @"Undefined";
}
- (void)setName:(NSString *)name{
    self.name = [name copy];
}

- (NSString *)name{
    return [self.name copy];
}

@end

我希望你能带来一点启发,经过几个月的这种编程,我越来越不确定能把它做好。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-15 16:36:19

这确实是每个Objective C程序员都会遇到的话题。有几件事需要知道:

实例变量与属性访问

在MyViewController中,

代码语言:javascript
复制
myObject = xxx;

代码语言:javascript
复制
self.myObject = xxx;

是两件不同的事情。第一个直接赋值给实例变量,既不释放到旧的引用实例,也不保留新赋值的实例。后者使用属性setter,从而释放旧的并保留新值。

释放

即使您已经声明了一个实现的属性,该属性负责保留和释放这些值,当您的对象(在本例中为MyViewController)被释放时,它也不会考虑释放。因此您必须在dealloc中显式释放它

代码语言:javascript
复制
-(void) dealloc {
  [myObject release];
  [super dealloc];
}

现在对您的代码执行

代码片段:

代码语言:javascript
复制
myObject = [[MyClass alloc] initPersonalised];

完全没问题。创建对象时,使用alloc和initXXX对。总是创建一个引用计数设置为1的实例。因此,通过直接将其赋值给实例变量,您可以创建一个干净的星座。我看不到创建实例的其他方法。

在MyClass中,您可以使用@synthesize name而不是@dynamic。然后编译器会自动实现namesetName:,你就不需要自己去做了。

最后,你失踪的dealloc

更新:

如果您使用:

代码语言:javascript
复制
self.myObject = [[MyClass alloc] initPersonalised];

这样就有了内存泄漏,因为initPesonalised将引用计数设置为1,而myObject的设置器将其增加到2。如果你想使用setter,那么我必须:

代码语言:javascript
复制
MyClass* mo = [[MyClass alloc] initPersonalised];
self.myObject = [[MyClass alloc] initPersonalised];
[mo release];

如果您不使用initXXX来创建新实例,情况就会有所不同。例如,类NSString有许多名为stringXXX的方法,这些方法创建一个新实例(或返回一个共享实例),该实例(在概念上)的引用计数为1,稍后将自动减1。那么你最好使用setter:

代码语言:javascript
复制
self.name = [NSString stringWithFormat: @"instance %d", cnt];

如果您想对字符串属性使用copy而不是retain (这是一种很好的做法),那么您可以像这样简单地声明您的属性:

代码语言:javascript
复制
@property (nonatomic, copy) NSString *name;

然后,当您使用@synthesize实现getter和setter时,编译器将使用copy而不是retain生成它们。

即使您使用@property和/或@synthesize来实现属性,NSString *name;也是必需的。

票数 1
EN

Stack Overflow用户

发布于 2011-05-15 16:28:57

你可以看看Memory Management Guide。它将帮助您更好地理解分配和保留概念;希望这对您有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2011-05-15 16:35:00

Alloc和init是始终并驾齐驱的方法。alloc为您的对象分配空间,而init将您的对象初始化为某个值。当您调用alloc时,您将负责稍后释放该对象。如果调用copy,您还需要负责稍后释放该对象。通常认为,在分配对象之后立即初始化对象是很好的做法。

现在,来回答我在代码中发现的问题。

代码语言:javascript
复制
   @interface MyViewController : UIViewController  {
      //Is the following line really necessary?
    MyClass *myObject;
}

那么这一行是必要的吗?这要看情况了。你的对象有一个MyClass作为属性有意义吗?这是一个只有你可以根据你的设计来回答的问题。我建议您更深入地学习面向对象编程。

代码语言:javascript
复制
- (void)defineObject
{
      //Here particularly, Why doesn't it work without both alloc and init
      //shouldn't "@property (nonatomic, retain) MyClass *myObject;" have done that already?
    myObject = [[MyClass alloc] initPersonalised];
    [myObject setName:@"my name"];
}

不一定。您只是提供了一个指向指定类型对象的指针。当您设置属性时,根据属性修饰符,您的类将知道如何处理MyObject。

这样,就不需要调用[yourObject copy]了。这样,您的属性将被复制,而不是被保留。但不要忘记稍后在-dealloc方法中释放它,就像保留属性一样。

总而言之,这是我建议你多学习的内容:

  • Object-Oriented编程(与您的问题无关,但我可以告诉您使用它并不舒服。Objective-C是高度面向对象的,所以你需要了解OOP)。
  • iOS内存管理。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6007230

复制
相关文章

相似问题

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