用前缀避免命名空间冲突
- 类似于Cocoa前缀NS、UI等,但是Apple宣称其保留使用所有“两字母前缀”,因此最好自定义前缀最好是三字母的。
- 若自己开发的程序库用到了第三方库,则应为其中的名称加上前缀
提供“全能初始化方法”
原因:
使其他初始化方法与底层数据解耦合,当底层数据存储机制发生改变时,只需要修改该函数的代码即可。
处理
在类中提供一个全能初始化方法,,其他初始化方法均应调用此方法
全能初始化方法与超类不同,则需要覆写超类中对应的方法
如果超类的初始化方法不适用于子类,那么应该覆写这个超类方法,并在其中抛出异常
//使用默认值
-(id)init {
return [self initWith......];
}
//抛出异常方法
-(id)init{
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must use initWith... instead."
userInfo:nil];
}
实现description方法
- 实现description方法返回一个有意义的字符串,用以描述该实例
-(NSString*)description{
return [NSString stringWithFormat:@"<%@ %@>", _firstName, _lastName];
}
//output:
//person = <Bob Smith>
- 若想在调试时打印出更详尽的对象描述信息,则应该实现debugDescription方法
-(NSString*)debugDescription{
return [NSString stringWithFormat:@"<%@: %p, \" %@ %@ \">", [self class], self, _firstName, _lastName];
}
//output:
//person = <EOCPerson: 0x7fb249c030f0, "Bob Smith">
//与description同时存在的原因在于,前者只在调试的时候输出,因此可以将类名、指针这些私有元素输出,但是普通描述信息只输出内容值
尽量使用不可变对象
不要把可变的collection作为属性公开,而应该提供相关的方法,以此修改对象中得可变collection
尽量创建不可变对象,公开的属性可设置为readonly,仅可内部修改属性可以在“class-continuation分类”中将其有readonly属性扩展为readwrite
//示例
//FSJAnimal.h
@interface FSJAnimal : NSObject
@property(nonatomic, copy, readonly) NSString *name;
@property(nonatomic, strong, readonly) NSSet *families;
-(id)initWithName:(NSString *)name;
-(void)addFamilies:(FSJAnimal *)animal;
-(void)removeFamilies:(FSJAnimal *)animal;
@end
//FSJAnimal.m
@interface FSJAnimal()
@property(nonatomic, copy, readwrite) NSString*name;
@end
@implementation FSJAnimal{
NSMutableSet *_internalFamilies;
}
//懒初始化
-(NSSet*)families{
return [_internalFamilies copy];
}
-(id)initWithName:(NSString *)name
{
if(self = [super init])
{
_name = name;
_internalFamilies = [[NSMutableSet alloc] init];
}
return self;
}
-(void)addFamilies:(FSJAnimal *)animal
{
[_internalFamilies addObject:animal];
}
-(void)removeFamilies:(FSJAnimal *)animal
{
[_internalFamilies removeObject:animal];
}
@end
为私有方法名加前缀
原因:
为了区分private方法和public方法,因为不管private和public方法都需要在implementation中实现,避免对public方法进行修改,避免影响其他类
Apple一般用下划线开头表示私有方法
理解Objective-C错误模型
- 处理严重错误时,建议采用抛出异常的方法
//抛出异常方法
-(id)init{
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must use initWith... instead."
userInfo:nil];
}
- 一般错误可采用委托方法或者NSError方法
//NSURLConnectionDelegate中NSURLConnection若出错会通过协议中的方法传给委托对象
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
//NSError方法是常见的经由方法“输出参数”返回给调用者
-(BOOL)doSomething:(NSError **)error{
if(/*there is an error*/){
if(error){
*error = [NSError errorWithDomain:domain code:code userInfo:userInfo];
}
return NO;
}else{
return YES;
}
}
//调用者可以仅获取结果不用知道具体错误,也可以查询具体错误
NSError *error = nil;
BOOL ret = [object doSomething:&error];;
if(error){
//There was an error
}
理解NSCopying协议
原因:
Objective-C中的深浅拷贝要比C++复杂一些,原因是Objective-C中提供了一些copy的方法,但是这些方法深浅难辨,以下做总结,具体参考以下链接。
http://blog.csdn.net/shawjan/article/details/48833307