gpt4 book ai didi

objective-c - 如何保留我自己的对象和属性

转载 作者:行者123 更新时间:2023-11-28 20:46:22 26 4
gpt4 key购买 nike

我不确定我是否理解分配和保留的工作原理。

最近发现NSString的属性没有保留,设置的时候必须加上[myString copy]。这让我想知道我是否误解了使用保留/分配的整个方式

拜托,有人可以告诉我我做的是否正确吗?我阅读了很多书并查看了开源项目,这让我意识到我可能从一开始就错了。

这是我的做法:

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

.

/**** 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"];
}

.

/**** 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

.

/**** 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

我希望你能带来一点启发,以这种方式编程几个月后,我越来越不确定是否能做好。

最佳答案

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

实例变量与属性访问

MyViewController 中,

myObject = xxx;

self.myObject = xxx;

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

解除分配

即使您已声明一个已实现的属性来负责保留和释放值,它也不会在您的对象(在您的情况下为 MyViewController)被释放时负责释放。因此,您必须在 dealloc 中显式释放它:

-(void) dealloc {
[myObject release];
[super dealloc];
}

现在你的代码:

片段:

myObject = [[MyClass alloc] initPersonalised];

完全没问题。当你创建一个对象时,你使用了一对 allocinitXXX。始终创建一个引用计数设置为 1 的实例。因此,通过将其直接分配给实例变量,您可以创建一个干净的星座。我看不到其他创建实例的方法。

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

最后,您缺少的 dealloc

更新:

如果您使用:

self.myObject = [[MyClass alloc] initPersonalised];

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

MyClass* mo = [[MyClass alloc] initPersonalised];
self.myObject = [[MyClass alloc] initPersonalised];
[mo release];

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

self.name = [NSString stringWithFormat: @"instance %d", cnt];

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

@property (nonatomic, copy) NSString *name;

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

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

关于objective-c - 如何保留我自己的对象和属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6007230/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com