《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个方法》

《Effective Objective-C 2.0编写高质量i

2019-01-28  本文已影响0人  Mr_WangZz

如果决定重用代码,那么我们在编写接口时,就会将其设计成易于复用的形式。这需要用到�Objective-C语言中常见的编程范式,同时还需要了解各种可能碰到的陷阱。

15. 使用前缀避免命名空间冲突

重名符号错误:duplicate symbol error

1). 选用的前缀应该是3个字母的,Apple保留了使用全部2个字母开头的权利。
如:

Apple: NSObject
项目中: WZZObject

2). 总是应该给C函数的命名也应加上前缀。如加上模块名、类名等。若出现问题,方便回溯。

要点总结:

16. 提供 全能初始化方法

要点总结:

17. 实现description

要想输出更为有用的信息,可以在定义的类中,覆写 description 方法,将描述此对象的字符串返回即可。

- (NSString *)description {
    
    return [NSString stringWithFormat:@"名字%@ _薪水%lu", self.name, (unsigned long)self.salary];
    
}

- (NSString *)debugDescription {
    return [NSString stringWithFormat:@"<%@: %p> 名字%@ _薪水%lu", [self class], self, self.name, (unsigned long)self.salary];
}

//输出:
NSLog: 名字Samara _薪水200
(lldb) po aEmployee
<EOCEmployeeDeveloper: 0x600000226640> 名字Samara _薪水200
要点总结:

18. 尽量使用不可变对象

//  EOCPerson.h

#import <Foundation/Foundation.h>

@interface EOCPerson : NSObject

@property (nonatomic, copy, readonly) NSString *firstName;

@property (nonatomic, copy, readonly) NSString *lastName;

@property (assign, readonly) NSUInteger age;

@property (nonatomic, strong, readonly) NSSet *friends;


- (id)initWithFirstName:(NSString *)firstName
               lastName:(NSString *)lastName;

@end




- (id)initWithFirstName:(NSString *)firstName
               lastName:(NSString *)lastName {

    if ((self = [super init])) {
        _firstName = firstName;
        _lastName = lastName;
    }
    return self;
}

/***********************/
//  EOCPerson.m

#import "EOCPerson.h"

@interface EOCPerson()

@property (nonatomic, copy, readwrite) NSString *firstName;

@property (nonatomic, copy, readwrite) NSString *lastName;

@end

@implementation EOCPerson {
    NSMutableSet *_mutableSet;
}

- (id)initWithFirstName:(NSString *)firstName
               lastName:(NSString *)lastName {

    if ((self = [super init])) {
        _firstName = firstName;
        _lastName = lastName;
        _mutableSet = [NSMutableSet new];
    }
    return self;
}

- (NSString *)firstName {
    return [_mutableSet copy];
}

- (void)addFriends:(NSSet *)objects {
    [_mutableSet addObject:objects];
}
- (void)removeFriends:(NSSet *)objects {
    if ([_mutableSet containsObject:objects]) {
        [_mutableSet removeObject:objects];
    }
}
@end
要点总结:

注意readonly 可以使用KVC(键值编码)修改这些值;
直接用类型信息查询功能查出属性所对应的实例变量在内存中的偏移量。

19. 使用清晰而协调的命名方式

方法的命名规则总结

如:-(NSString *)hasPrefix:(NSString *)string;

要点总结:

20. 为私有方法名加上前缀

/** 公开方法 */
- (void)publicMethod {}
/** 私有方法 “p_”开头 */
- (void)p_privateMethod {}
要点总结:

21. 理解Objective-C错误模型

/** 定义错误组件 */
//.h
//专用的“错误范围”字符串
extern NSString *const EOCErrorDomain;

//错误码
typedef NS_ENUM(NSUInteger, EOCErrorCode) {
    EOCErrorUnkown                  = -1,
    EOCErrorInternalInconsistency   = 100,
    EOCErrorGeneralFault            = 105,
    EOCErrorBadInput                = 500,
};

//.m
NSString *const EOCErrorDomain = @"EOCErrorDomain";

//例如
- (void)doSomething:(EOCError* *)error;
要点总结:
@throw [NSException exceptionWithName:@"Error" reason:@"can not init" userInfo:nil];

22. 理解 NSCopying 协议

要点总结

需求是:使用对象时经常需要拷贝它。

//浅拷贝
- (id)copyWithZone:(NSZone *)zone {
    
    EOCPerson *copy = [[[self class] allocWithZone:zone] initWithFirstName:_firstName lastName:_lastName];
    copy->_mutableSet = [_friends mutableCopy];
    return copy;
}

//执行深拷贝
- (id)deepCopy {
    
    EOCPerson *copy = [[[self class] alloc] initWithFirstName:_firstName lastName:_lastName];
    
    copy->_mutableSet = [[NSMutableSet alloc] initWithSet:_friends copyItems:YES];
    
    return copy;
}

系列文章

上一篇下一篇

猜你喜欢

热点阅读