Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 我是否应该释放一个非空属性;如果是,怎么做?_Objective C_Swift - Fatal编程技术网

Objective c 我是否应该释放一个非空属性;如果是,怎么做?

Objective c 我是否应该释放一个非空属性;如果是,怎么做?,objective-c,swift,Objective C,Swift,我向Swift(基于)展示了Objective-C项目中的一些属性,但没有Objective-C方面的经验,因此我在这里有点深不可测,请耐心听我说 我想知道如何正确地解除非null属性的锁定(或者是否有必要!)。我通过将null属性surface设置为null,临时解除了对nonnull属性的锁定(方法与对null部分语音的操作相同)。但是,这会提示以下警告: 传递给需要非Null参数的被调用方的Null 。。。所以我想知道这是否是多余的。在节点类的dealloc块期间,我是否应该做些什么来处理

我向Swift(基于)展示了Objective-C项目中的一些属性,但没有Objective-C方面的经验,因此我在这里有点深不可测,请耐心听我说

我想知道如何正确地解除
非null属性的锁定(或者是否有必要!)。我通过将
null
属性
surface
设置为
null
,临时解除了对
nonnull
属性的锁定(方法与对
null
部分语音的操作相同)。但是,这会提示以下警告:

传递给需要非Null参数的被调用方的Null

。。。所以我想知道这是否是多余的。在
节点
类的
dealloc
块期间,我是否应该做些什么来处理我的
nonnull
属性

给定接口,
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

如果使用手动内存管理,则只需
释放
存储在properties backing变量中的对象即可。由于您已将支持变量命名为与属性相同的名称,请使用
->
清楚地引用支持变量:

[self->surface release];
或者,如果要对赋值执行此操作,只需指定空字符串文字:

self.surface = @"";
字符串文字是在编译时创建的,在程序执行过程中始终存在,占用的空间非常小。赋值将导致属性中上一个值的
释放
(如果引用计数达到零,则取消分配),就像赋值
为nil
(或任何其他值)一样

HTH

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

// Node.h
@interface Node : NSObject

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

@end
实现文件中不需要
@synthesis
语句。 编译器将自动创建实例变量
\u表面
\u部分语音
,并创建访问器方法

- (NSString *) surface;
- (void)setSurface:(NSString *)value;
- (NSString *)partOfSpeech;
- (void)setPartOfSpeech:(NSString *)value;
哪一个做“正确的事情”,带弧还是不带弧。您可以覆盖 如果您想实现一些自定义逻辑,但不必实现像
setPartOfSpeech
这样的标准设置器,那么就可以使用这些方法

如果使用ARC(自动参考计数),则仅此而已, 不需要更多了。及 我真的建议这样做。编译器在编译时插入所需的retain/release调用,在避免 不必要的电话。例如,见

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

但要回答您的问题:有了MRC,您必须发布
dealloc中的实例变量

- (void)dealloc {
    [_surface release];
    [_partOfSpeech release];
    [super dealloc];
}
如《高级内存管理编程指南》中所述

您不应使用
dealloc
中的访问器方法,就像在

self.surface = nil;
self.partOfSpeech = nil;

请参阅。

@Ron感谢您指出这一点。它是一个C++项目的Obj-C包装器,(它最终将标题暴露给SWIFT!),所以我被混淆了。正如您所说,这里提供的代码纯粹是Obj-C。不使用ARC(自动引用计数)有什么特殊原因吗?@MartinR由于这是一个高性能、行业标准令牌服务器的包装器,因此可能有一些理由支持对内存管理进行严格、明确的控制。但我认为,在实践中,Xcode无论如何都会覆盖内存管理以使用ARC(如果我理解正确的话)。至于我的“特殊原因”,我会说,如果没有更多的话,“作为一个学习练习”。这些代码片段会去哪里?它们是否会取代我当前放置的
self.surface=nil?我认为在上一段中,您的意思是不应使用访问器方法作为引用状态。
self.surface = nil;
self.partOfSpeech = nil;