13.尽量使用不可变对象
//In header file
@interface ViewController : UIViewController
@property(nonatomic,strong,readonly)NSString *firstName;
@property(nonatomic,strong)NSSet *friends;
- (void)addFriends:(NSSet *)objects;
- (void)removeFriends:(NSSet *)objects;
@end
//In implementation file
@interface ViewController ()
@property(nonatomic,strong,readwrite)NSString *firstName;
@end
@implementation ViewController{
NSMutableSet *_internalFriends;
}
- (NSSet *)friends
{
return [_internalFriends copy];
}
- (void)addFriends:(NSSet *)objects
{
[_internalFriends addObject:objects];
}
- (void)removeFriends:(NSSet *)objects
{
[_internalFriends removeObject:objects];
}
为了避免外界随意改动你的代码,尽量把暴露的属性设置为只读,即使是可变的类型,NSMutableDictionary ,NSMutableArray,NSMutableSet,
也在外面定义为不可变,并提供add ,remove,
方法操作可变对象,
14.为私有方法加前缀
用下划线_
开头 或者以p(private)
开头,代表私有方法,建议p_resetData
- (void)p_resetData
{
NSLog(@"%s",__func__);
}
- (void)_resetData
{
NSLog(@"%s",__func__);
}
14.通过委托(Delegate)与数据源协议(DataSource)进行对象间通信
#import <Foundation/Foundation.h>
#import "EOCNetworkFetcher.h"
NS_ASSUME_NONNULL_BEGIN
@class EOCNetworkFetcher;
struct data {
unsigned int fieldA : 8;
unsigned int fieldB : 4;
unsigned int fieldC : 2;
unsigned int fieldD : 1;
};
@protocol EOCNetworkFetcherDelegate <NSObject>
@optional
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher
didReceiveData:(NSData *)data;
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher
didFailWithError:(NSError *)error;
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher
didUpdateProgressTo:(float )progress;
@end
//In header file - EOCNetworkFetcher
#import <Foundation/Foundation.h>
#import "EOCNetworkFetcherDelegate.h"
@interface EOCNetworkFetcher : NSObject
@property(nonatomic,weak,nullable)id <EOCNetworkFetcherDelegate>delegate;
@end
//In implementation file - EOCNetworkFetcher
#import "EOCNetworkFetcher.h"
@interface EOCNetworkFetcher() <EOCNetworkFetcherDelegate>
{
struct {
unsigned int didReceiveData : 1;
unsigned int didFailWithError : 1;
unsigned int didUpdateProgress : 1;
}_delegateFlags;
}
@end
@implementation EOCNetworkFetcher
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data
{
if (_delegateFlags.didReceiveData) {
[_delegate networkFetcher:fetcher didReceiveData:data];
}
}
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailWithError:(NSError *)error
{
if (_delegateFlags.didFailWithError) {
[_delegate networkFetcher:fetcher didFailWithError:error];
}
}
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didUpdateProgressTo:(float)progress
{
if (_delegateFlags.didUpdateProgress) {
[_delegate networkFetcher:fetcher didUpdateProgressTo:progress];
}
}
- (void)setDelegate:(id<EOCNetworkFetcherDelegate>)delegate
{
_delegate = delegate;
_delegateFlags.didReceiveData = [delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
_delegateFlags.didFailWithError = [delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
_delegateFlags.didUpdateProgress = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}
@end
这种情况适用于频繁调用代理的某些方法的时候,能够一定程度提高效率
15.将类的实现代码分散到便于管理的数个分类当中 把统一类型的方法,放到对应的分类当中,也可以拆分成不同的文件中
这样做的好处就是 把逻辑区分出来,便于管理,将不同的代码归于不同的功能区;
把封装数据所用的全部属性都定义在主接口里,在分类中可以定义存取方法,但尽量不要定义属性
16.在dealloc方法中只释放引用并解除监听
1.在dealloc方法里,应该做的事情就是释放指向其他对象的引用,并取消KVO,或通知,不要做其他事
2.如果对象持有文件描述符等系统资源,那么应该专门编写一个方法来释放此种类,这样的类要和其使用者约定:用完资源之后必须调用close方法
3.执行一步任务的方法不应该在dealloc里调用;只能在正常状态下执行的那些方法也不应该在dealloc里调用,因为此时对象已经处于正在回收的状态了.
17.编写"异常安全代码"时留意内存管理问题
EOCSomeClass *object;
@try {
object =[ [EOCSomeClass alloc] init];
[object doSomethinThatMayThrow];
}
@catch (...) {
NSLog(@"whopps,there was an error. oh well...");
}
@finally {
[object release];
}
1.捕获异常时,一定要注意将try块内所创立的对象清理干净
2.在默认情况下,ARC不生成安全处理异常所需的清理代码,开启编译器标志(-fobjc-arc-exceptions
)后可生成这种代码,不过会导致应用程序变大,而且会降低运行效率
18.以"自动释放池块"降低内存峰值
1.自动释放池排布在栈中,对象收到autorelease消息后,系统将其放入最顶端的池子里
2.合理运用自动释放池,可降低应用程序的内存峰值.
3.autoreleasepool这种新式写法能创建出更为轻便的自动释放池.
网友评论