Iphone 为NSKeyedArchiver和内存泄漏实现NSCoding
我有一个自定义对象,我正在使用NSKeyedArchiver将其转换为NSData,以便我的自定义对象实现NSCoding协议。但是当我运行Instruments工具时,它告诉我我的initWithCoder方法在initWithCoder中有许多泄漏的NSCFString对象 实现NSCoding协议的正确方法是什么 我的班级:Iphone 为NSKeyedArchiver和内存泄漏实现NSCoding,iphone,memory-leaks,Iphone,Memory Leaks,我有一个自定义对象,我正在使用NSKeyedArchiver将其转换为NSData,以便我的自定义对象实现NSCoding协议。但是当我运行Instruments工具时,它告诉我我的initWithCoder方法在initWithCoder中有许多泄漏的NSCFString对象 实现NSCoding协议的正确方法是什么 我的班级: @interface EventProfile : NSObject <NSCoding> NSString *eventTitle;
@interface EventProfile : NSObject <NSCoding>
NSString *eventTitle;
NSString *groupName;
@end
@implementation EventProfile
// NSCoding methods
-(id) initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
eventTitle = [[decoder decodeObjectForKey:@"eventTitle"] retain];
groupName = [[decoder decodeObjectForKey:@"groupName"] retain];
}
return self;
}
-(void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.eventTitle forKey:@"eventTitle"];
[encoder encodeObject:self.groupName forKey:@"groupName"];
}
// Memory management
- (void)dealloc
{
[eventTitle release];
[groupName release];
[super dealloc];
}
@end
@接口事件配置文件:NSObject
NSString*eventTitle;
NSString*groupName;
@结束
@实现事件配置文件
//非编码方法
-(id)initWithCoder:(NSCoder*)解码器
{
if(self=[super init])
{
eventTitle=[[decoder decodeObjectForKey:@“eventTitle”]保留];
groupName=[[decoder decodeObjectForKey:@“groupName”]保留];
}
回归自我;
}
-(void)编码器WithCoder:(NSCoder*)编码器
{
[编码器编码对象:self.eventTitle forKey:@“eventTitle”];
[编码器编码对象:self.groupName forKey:@“groupName”];
}
//内存管理
-(无效)解除锁定
{
[事件标题发布];
[群组名称发布];
[super dealoc];
}
@结束
要实现encodeWithCoder:您应该检查对象的所有基本属性,并使用NSCoder上的各种方法对它们进行编码。对于对象属性,只需使用encodeObject:forKey:。密钥可以是描述正在编码的属性的短字符串:
class Book: NSObject, NSCoding {
var title: String
var author: String
var pageCount: Int
var categories: [String]
var available: Bool
// Memberwise initializer
init(title: String, author: String, pageCount: Int, categories: [String], available: Bool) {
self.title = title
self.author = author
self.pageCount = pageCount
self.categories = categories
self.available = available
}
// MARK: NSCoding
required convenience init?(coder decoder: NSCoder) {
guard let title = decoder.decodeObjectForKey("title") as? String,
let author = decoder.decodeObjectForKey("author") as? String,
let categories = decoder.decodeObjectForKey("categories") as? [String]
else { return nil }
self.init(
title: title,
author: author,
pageCount: decoder.decodeIntegerForKey("pageCount"),
categories: categories,
available: decoder.decodeBoolForKey("available")
)
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.title, forKey: "title")
coder.encodeObject(self.author, forKey: "author")
coder.encodeInt(Int32(self.pageCount), forKey: "pageCount")
coder.encodeObject(self.categories, forKey: "categories")
coder.encodeBool(self.available, forKey: "available")
}
}
正如您所看到的,NSCoding主要是样板。每个属性都作为对象或类型进行编码或解码,每次使用的属性名称作为键。(一些开发人员喜欢为每个键路径定义NSString*常量,但这通常是不必要的)。eventTitle和
groupName
属性的定义是什么?如果它们是copy
,我觉得一切正常。但是如果它们是意外地分配的,您可能会遇到问题。您是否也可以在initWithCoder:
方法中使用self.eventTitle
和self.groupName
测试运行代码?除此之外,泄漏可能是在另一个位置使用EventTitle
类的位置。是的,您的界面没有显示属性定义,但您使用的是self.EventTitle
和self.groupName
内部encodeWithCoder:
??