这是一个很好的(类似Cocoa,Apple批准的)模型类吗?

and*_*n22 3 cocoa objective-c models cocoa-design-patterns

我一直在使用Objective-C,但我并没有很好地遵循Apple的指导方针.最近我读了Cocoa设计模式模型对象实现指南,我正在尝试做一些非常简单的事情,但是做得非常好.

我错过了任何重大概念吗?请不要提self = [super init]; 已经在SO上多次报道了.#pragma mark尽管如此,请随意批评我的!

#import "IRTileset.h"
#import "IRTileTemplate.h"

@interface IRTileset () //No longer lists protocols because of Felixyz

@property (retain) NSMutableArray* tileTemplates; //Added because of TechZen

@end

#pragma mark -
@implementation IRTileset

#pragma mark -
#pragma mark Initialization

- (IRTileset*)init
{
    if (![super init])
    {
        return nil;
    }

    tileTemplates = [NSMutableArray new];

    return self;
}

- (void)dealloc
{
    [tileTemplates release];
    [uniqueID release]; //Added because of Felixyz (and because OOPS. Gosh.)
    [super dealloc]; //Moved from beginning to end because of Abizern
}

#pragma mark -
#pragma mark Copying/Archiving

- (IRTileset*)copyWithZone:(NSZone*)zone
{
    IRTileset* copy = [IRTileset new];
    [copy setTileTemplates:tileTemplates]; //No longer insertTileTemplates: because of Peter Hosey
    [copy setUniqueID:uniqueID];

    return copy; //No longer [copy autorelease] because of Jared P
}

- (void)encodeWithCoder:(NSCoder*)encoder
{
    [encoder encodeObject:uniqueID forKey:@"uniqueID"];
    [encoder encodeObject:tileTemplates forKey:@"tileTemplates"];
}

- (IRTileset*)initWithCoder:(NSCoder*)decoder
{
    [self init];

    [self setUniqueID:[decoder decodeObjectForKey:@"uniqueID"]];
    [self setTileTemplates:[decoder decodeObjectForKey:@"tileTemplates"]]; //No longer insertTileTemplates: because of Peter Hosey

    return self;
}

#pragma mark -
#pragma mark Public Accessors

@synthesize uniqueID;
@synthesize tileTemplates;

- (NSUInteger)countOfTileTemplates
{
    return [tileTemplates count];
}

- (void)insertTileTemplates:(NSArray*)someTileTemplates atIndexes:(NSIndexSet*)indexes
{
    [tileTemplates insertObjects:someTileTemplates atIndexes:indexes];
}

- (void)removeTileTemplatesAtIndexes:(NSIndexSet*)indexes
{
    [tileTemplates removeObjectsAtIndexes:indexes];
}

//These are for later.
#pragma mark -
#pragma mark Private Accessors

#pragma mark -
#pragma mark Other

@end
Run Code Online (Sandbox Code Playgroud)

(编辑:到目前为止,我已经做了修改并评论了哪些答案可以讨论它们,以防有人知道原因.)

Pet*_*sey 5

请不要提self = [super init]......

所以,你为什么不那样做?

同样适用initWithCoder::您应该使用返回的对象[self init],而不是假设它初始化了初始对象.

- (void)dealloc
{
    [super dealloc];
    [tileTemplates release];
}
Run Code Online (Sandbox Code Playgroud)

正如Abizern在评论中所说,[super dealloc]应该到最后.否则,您正在访问已释放对象的实例变量.

- (IRTileTemplate*)copyWithZone:(NSZone*)zone
Run Code Online (Sandbox Code Playgroud)

这里的返回类型应该是id,匹配NSCopying协议声明的返回类型.

{
    IRTileset* copy = [IRTileset new];
    [copy insertTileTemplates:tileTemplates atIndexes:[NSIndexSet indexSetWithIndex:0]];
    [copy setUniqueID:uniqueID];
Run Code Online (Sandbox Code Playgroud)

您在一个索引处插入零个或多个对象.使用范围创建索引集:location = 0,length = tileTemplates数组的计数.更好的是,只需分配给整个房产价值:

copy.tileTemplates = self.tileTemplates;
Run Code Online (Sandbox Code Playgroud)

或者直接访问实例变量:

copy->tileTemplates = [tileTemplates copy];
Run Code Online (Sandbox Code Playgroud)

(请注意,copy绕过属性访问器时必须自己动手,并且copy代表副本使用数组.)

    return [copy autorelease];
}
Run Code Online (Sandbox Code Playgroud)

copyWithZone:不应该返回自动释放的对象.根据内存管理规则,调用者拥有copycopyWithZone:拥有副本,这意味着调用者的工作是释放它,而不是copyWithZone:.

@synthesize tileTemplates;
[et al]
Run Code Online (Sandbox Code Playgroud)

您可能还想实现单对象数组访问器:

- (void) insertObjectInTileTemplates:(IRTileTemplate *)template atIndex:(NSUInteger)idx;
- (void) removeObjectFromTileTemplatesAtIndex:(NSUInteger)idx;
Run Code Online (Sandbox Code Playgroud)

当然,这是可选的.