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)
(编辑:到目前为止,我已经做了修改并评论了哪些答案可以讨论它们,以防有人知道原因.)
请不要提
self = [super init]......
所以,你为什么不那样做?
同样适用initWithCoder::您应该使用返回的对象[self init],而不是假设它初始化了初始对象.
Run Code Online (Sandbox Code Playgroud)- (void)dealloc { [super dealloc]; [tileTemplates release]; }
正如Abizern在评论中所说,[super dealloc]应该到最后.否则,您正在访问已释放对象的实例变量.
Run Code Online (Sandbox Code Playgroud)- (IRTileTemplate*)copyWithZone:(NSZone*)zone
这里的返回类型应该是id,匹配NSCopying协议声明的返回类型.
Run Code Online (Sandbox Code Playgroud){ IRTileset* copy = [IRTileset new]; [copy insertTileTemplates:tileTemplates atIndexes:[NSIndexSet indexSetWithIndex:0]]; [copy setUniqueID:uniqueID];
您在一个索引处插入零个或多个对象.使用范围创建索引集: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代表副本使用数组.)
Run Code Online (Sandbox Code Playgroud)return [copy autorelease]; }
copyWithZone:不应该返回自动释放的对象.根据内存管理规则,调用者拥有copy或copyWithZone:拥有副本,这意味着调用者的工作是释放它,而不是copyWithZone:.
Run Code Online (Sandbox Code Playgroud)@synthesize tileTemplates; [et al]
您可能还想实现单对象数组访问器:
- (void) insertObjectInTileTemplates:(IRTileTemplate *)template atIndex:(NSUInteger)idx;
- (void) removeObjectFromTileTemplatesAtIndex:(NSUInteger)idx;
Run Code Online (Sandbox Code Playgroud)
当然,这是可选的.