美文网首页
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