[摘要]Effective Objective-C 2.0(二)

用前缀避免命名空间冲突

  • 类似于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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值