Iphone 为NSKeyedArchiver和内存泄漏实现NSCoding

Iphone 为NSKeyedArchiver和内存泄漏实现NSCoding,iphone,memory-leaks,Iphone,Memory Leaks,我有一个自定义对象,我正在使用NSKeyedArchiver将其转换为NSData,以便我的自定义对象实现NSCoding协议。但是当我运行Instruments工具时,它告诉我我的initWithCoder方法在initWithCoder中有许多泄漏的NSCFString对象 实现NSCoding协议的正确方法是什么 我的班级: @interface EventProfile : NSObject <NSCoding> NSString *eventTitle;

我有一个自定义对象,我正在使用NSKeyedArchiver将其转换为NSData,以便我的自定义对象实现NSCoding协议。但是当我运行Instruments工具时,它告诉我我的initWithCoder方法在initWithCoder中有许多泄漏的NSCFString对象

实现NSCoding协议的正确方法是什么

我的班级:

@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:
??