我应该取消一个非空的财产;如果是的话,怎么样?

时间:2017-11-11 11:52:29

标签: objective-c swift

我将Objective-C项目中的一些属性暴露给Swift(基于this repo),但是没有Objective-C的经验,所以我很喜欢我的深度在这里,所以请耐心等待。

我想知道如何正确释放nonnull属性(或者根本不需要它!)。我通过将nonnull属性surface设置为null来暂时解除对nullable属性partOfSpeech的约束(与nonnull {{1 }})。但是,这会提示以下警告:

  

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

...所以我想知道它是否多余。在Node班级dealloc阻止期间,我应该做些什么来处理我的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]; 的生命周期是这样的:

http://armafix.juvenatemediatest.co.uk

2 个答案:

答案 0 :(得分:2)

首先:编译器可以自动合成实例变量和 您的房产的二传手/吸气剂。所以你的界面应该只是

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

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

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

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

但要回答你的问题:使用MRC你必须释放 dealloc

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

,如高级内存管理编程指南中的Memory Management Policy&#34;中所述。

您应 使用dealloc中的访问者方法,而不是

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

请参阅Don’t Use Accessor Methods in Initializer Methods and dealloc

答案 1 :(得分:1)

如果使用手动内存管理,则只能release存储在属性支持变量中的对象。由于您已将支持变量命名为与属性相同,因此使用->来清楚地引用支持变量:

[self->surface release];

或者,如果您想通过赋值执行此操作,只需指定空字符串文字:

self.surface = @"";

字符串文字在编译时创建,贯穿整个程序执行,占用的空间非常小。赋值将导致属性中前一个值的release(如果引用计数达到零则释放),就像分配nil(或任何其他值)一样。

HTH