gpt4 book ai didi

objective-c - 我应该释放一个非空属性吗?如果是这样,怎么办?

转载 作者:搜寻专家 更新时间:2023-10-31 19:27:41 25 4
gpt4 key购买 nike

我正在将 Objective-C 项目中的一些属性公开给 Swift(基于 this repo ),但我没有使用 Objective-C 的经验,所以我在这里有点力不从心,所以请耐心等待。

我想知道如何正确释放一个nonnull 属性(或者它是否有必要!)。我暂时取消分配了 nonnull 属性 surface,方法是将其设置为 null(与 的处理方式相同)可为空 partOfSpeech)。但是,这会提示以下警告:

Null passed to a callee that requires a non-null argument

...所以我想知道它是否多余。在 Node 类的 dealloc block 期间,我应该做些什么来处理我的 nonnull 属性?

给定接口(interface),node.h:

@interface Node : NSObject {
NSString *surface;
NSString *partOfSpeech;
}

@property (nonatomic, retain, nonnull) NSString *surface;
@property (nonatomic, retain, nullable) NSString *partOfSpeech;

- (nullable NSString *)partOfSpeech;

@end

...以及实现,node.m:

@implementation Node

@synthesize surface;
@synthesize partOfSpeech;

// surface is assumed to be set post-initialisation.

- (void)setPartOfSpeech:(NSString *)value {
if (partOfSpeech) [partOfSpeech release];
partOfSpeech = value ? [value retain] : nil;
}

- (NSString *)partOfSpeech {
if (!features || [features count] < 1) return nil;
return [features objectAtIndex:0];
}

- (void)dealloc {
// WARNING: "Null passed to a callee that requires a non-null argument"
self.surface = nil;
self.partOfSpeech = nil;
[super dealloc];
}

@end

... 假设 Node 的生命周期是这样的:

    Node *newNode = [Node new];
newNode.surface = [[[NSString alloc] initWithBytes:node->surface length:node->length encoding:NSUTF8StringEncoding] autorelease];
// ... Do stuff with newNode (eg. add to array of Node)...
[newNode release];

最佳答案

第一:编译器可以自动合成实例变量和您的属性的 setter/getter。所以你的界面应该只是

// Node.h
@interface Node : NSObject

@property (nonatomic, retain, nonnull) NSString *surface;
@property (nonatomic, retain, nullable) NSString *partOfSpeech;

@end

并且在实现文件中不需要@synthesize语句。编译器会自动创建实例变量_surface_partOfSpeech,以及创建访问器方法

- (NSString *) surface;
- (void)setSurface:(NSString *)value;
- (NSString *)partOfSpeech;
- (void)setPartOfSpeech:(NSString *)value;

在有或没有 ARC 的情况下做“正确的事”。你可以覆盖这些方法,如果你想实现一些自定义逻辑,但你不必像你的 setPartOfSpeech 那样实现标准 setter 。

如果你使用ARC(自动引用计数)那么就是这样,仅此而已。和我真的建议这样做。编译器在编译时插入所需的保留/释放调用,并且非常聪明地避免不必要的电话。参见示例

关于一些比较。使用 MRC(手动引用计数),您的代码甚至可能更慢,或者有内存泄漏。

但要回答您的问题:对于 MRC,您必须发布dealloc

中的实例变量
- (void)dealloc {
[_surface release];
[_partOfSpeech release];
[super dealloc];
}

Memory Management Policy 中所述在《高级内存管理编程指南》中。

你应该像在你的

中那样使用 dealloc中的访问器方法
self.surface = nil;
self.partOfSpeech = nil;

参见 Don’t Use Accessor Methods in Initializer Methods and dealloc .

关于objective-c - 我应该释放一个非空属性吗?如果是这样,怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47237590/

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