我将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
答案 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