美文网首页
iOS - OC <<编写高质量iOS与OS X代码的多个有效方

iOS - OC <<编写高质量iOS与OS X代码的多个有效方

作者: 洧中苇_4187 | 来源:发表于2020-09-21 15:03 被阅读0次

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这种新式写法能创建出更为轻便的自动释放池.

相关文章

网友评论

      本文标题:iOS - OC <<编写高质量iOS与OS X代码的多个有效方

      本文链接:https://www.haomeiwen.com/subject/hgfryktx.html