美文网首页
一点工作经验

一点工作经验

作者: mkb2 | 来源:发表于2017-11-02 17:59 被阅读80次

    作者:柠檬跑步 王鑫

    总结了一些好的习惯,分享一下。
    一起共勉。

    • 面向对象开发
    • id的使用
    • 提示文字的统一
    • 列表控制器使用LRBasicListController.swift
    • GXBaseViewController只应该添加分类,而不是添加方法
    • 属性不应该全部暴露在.h文件中,只有给外界使用的变量才放到.h文件中,必要的使用使用readOnly关键字
    • 封装代码,封装view,封装model,封装一切可能封装的东西
    • 分类名称的写法
    • view的高度写成常量
    • 项目中少用storybaord,以及使用他的注意项
    • 三个及以上的变量必须要换行,代码的大小写统一
    • .view.frame = CGRect.init(x:lx,y:ly,width:lW,height:lH)的写法
    • 使用胖model给控制器减肥,暴露出一个属性,可以让大家减少重复的计算
    • 不要去修改牛逼的第三方。sd,afn 我们项目有修改的情况,消耗性能
    • 不要无用的打印
    • Block的写法
    • 图片的命名
    • 指定一些颜色,字体,等宏定义
    • 给控制器瘦身
    • 属性的写法,nonamaticstrongreadonly
    • 特殊代码
    • 父类不要控制子类的属性,应该在子类中写

    面向对象开发

    开发必须要面向对象开发,决不允许面向字典开发
    面向字典容易出错,不好复用代码等.目前项目都是面向字典开发的

    [图片上传失败...(image-927c65-1509616761159)]

    [图片上传失败...(image-4a944b-1509616761160)]

    //保存房间列表实体
    for(NSDictionary *dic in [response.data objectForKey:@"rooms"]){
        Rooms *rooms = [Rooms roomsWithDic:dic];
        [weakSelf.roomsArray addObject:rooms];
    }
    

    这里应该注意

    • 1.面向字典开发
    • 2.三目运算符的使用不应该太长
      只有可控的时候,我们才能使用三目
      • 如: NSInteger age = user.gender == 1?0:1
      • !self.avatarTapBlock?:self.avatarTapBlock();
    • 3.学习使用Mantle或者MJExtension,用第三方直接字典转模型,演示一下使用方法
    //保存房间列表实体
    NSArray *keyValues = [response.data objectForKey:@"room_list"];
    NSArray *rooms = [Rooms mj_objectArrayWithKeyValuesArray:keyValues context:nil];
    [weakSelf.resultRooms addObjectsFromArray:rooms];
    

    id的使用
    • 凡是使用id的时候,不论用字符串类型,还是NSNumber(最好使用NString)都要和后台确定一下,用于统一.这样可以减少各种NSNumber和字符串之间的转化。
    • 别用int在OC中,可以使用NSInteger,少用int
    • 如果是id是模型Topic的,我们应该使用tip,减少id给我带来的影响.

    提示文字的统一

    这个就是涉及到了文字的处理,如果我们没有国际化,其实也是可以将常用文字,或者所有的文字全都统一处理,这样将来修改起来比较好用.

    
    static NSString * const LRLimitRunRoomNameTextLengthKey   = @"最多允许输入10个字哦~";
    static NSString * const LRHaveNetTheFoundationCanUseKey   = @"有网络才能进行挑战呦";
    static NSString * const LROpenLemonRunLocationNoticeKey    = @"请确保定位授权对柠檬跑步开放,\n并移动到"; 
    static NSString * const LROpenSystemLocationNoticeKey          = @"GPS未开启,无法获取当前位置";
    static NSString * const LRLocatButtonWhereAreYouKey            = @"你在哪里?";
    

    包括全局数据常量也应该如此,例如全马和半马的数据。项目中目前有,但是没有格式不对


    列表控制器使用LRBasicListController.swift

    只要是列表页控制器,都可以直接继承控制器
    实现功能:

    • 1.上拉加载上拉刷新功能
    • 2.提供了一个load数据方法给子类,只需关注要做的网络请求,其他的不用管理
    • 3.自动数据操作
    • 4.无网络情况
    • 5.无数据空白页情况

    GXBaseViewController只应该添加分类,而不是添加方法

    [图片上传失败...(image-774d60-1509616761160)]

    还有GXBaseViewControllershowHUD方法等,建议使用分类


    属性不应该全部暴露在.h文件中,只有给外界使用的变量才放到.h文件中,必要的使用使用readOnly关键字

    interface LRMineViewController : GXBaseViewController<EMContactManagerDelegate,EMChatManagerDelegate>
    
    property (weak, nonatomic) IBOutlet UITableView *mineTableView;
    property (weak, nonatomic) IBOutlet UIView *headerView;
    property (weak, nonatomic) IBOutlet UIImageView *topImage;
    property (weak, nonatomic) IBOutlet UIImageView *headShadow;
    property (weak, nonatomic) IBOutlet UIImageView *headImage;
    property (weak, nonatomic) IBOutlet UIImageView *genderImage;
    property (weak, nonatomic) IBOutlet UILabel *nameLabel;
    property (weak, nonatomic) IBOutlet UIImageView *mineIcon1;
    @property (weak, nonatomic) IBOutlet UILabel *mineIconBottom1;
    @property (weak, nonatomic) IBOutlet UIImageView *mineIcon2;
    @property (weak, nonatomic) IBOutlet UILabel *mineIconBottom2;
    @property (weak, nonatomic) IBOutlet UIImageView *mineIcon3;
    @property (weak, nonatomic) IBOutlet UILabel *mineIconBottom3;
    @property (weak, nonatomic) IBOutlet UIImageView *levelImage;
    @property (weak, nonatomic) IBOutlet UILabel *locationLabel;
    @property (weak, nonatomic) IBOutlet UIImageView *medalNew;
    @property (weak, nonatomic) IBOutlet UIImageView *bestNew;
    @property (weak, nonatomic) IBOutlet UILabel *hisDurationLabel;
    @property (weak, nonatomic) IBOutlet UILabel *hisDurationBottomLabel;
    @property (weak, nonatomic) IBOutlet UILabel *hisDistanceLabel;
    @property (weak, nonatomic) IBOutlet UILabel *hisDistanceBottomLabel;
    @property (weak, nonatomic) IBOutlet UIButton *hisBackBtn;
    @property (weak, nonatomic) IBOutlet UIButton *friendStatusButton;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *hisDurationBottom;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewBottom;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *mineIcon1Gap;//65
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *mineIcon3Gap;//65
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *friendBtnLeading;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *friendBtnTrailing;
    @property (strong, nonatomic) NSArray *leftStrArray;
    @property (strong, nonatomic) NSMutableArray *collectionArray;
    @property (strong, nonatomic) NSString *userId;
    @property (strong, nonatomic) NSDictionary *medalListDic;
    @property (strong, nonatomic) NSString *userAvatar;//别人头像的链接url
    @property (strong, nonatomic) NSDictionary *infoDictionary;
    @property (strong, nonatomic) UICollectionView *medalCollectionView;
    @property (assign, nonatomic) BOOL isFriend;//是否是好友关系
    @property (strong, nonatomic) LRAvatarView *avatarView;
    @property (assign, nonatomic) BOOL isFromPop;//如果是pop回来 不需要navigation动画
    @property (assign, nonatomic) BOOL isFromPush;//如果是从push进来的,navigation隐藏时animation设为YES否则NO
    @property (copy, nonatomic) NSString *pointsStr,*gradeStr,*feedStr; //积分 等级 动态
    @property (copy, nonatomic) NSString *start_pos;
    @property (strong, nonatomic) NSMutableArray *feedsArray;
    @property (assign, nonatomic) BOOL isFromAddFriend;//从添加好友进来,直接底部显示‘加为好友’
    @property (assign, nonatomic) BOOL isFromFriend;//从好友界面进来
    @property (assign, nonatomic) BOOL isFromChatView;//从聊天页面进来
    @property (assign, nonatomic) BOOL isFromDiscover;//从发现首页进来,返回时需要执行好友换一组操作
    @property (strong, nonatomic) NSString *discoverId;//发现Id
    @end
    

    外界可以直接修改所有的参数,之所以别人将这段代码写成这个样子,主要是因为他不想在.m文件中在写interface~

    .h文件
    @interface LRComment : LRInteract
    @property(copy,nonatomic)  NSString *parentContent;/** 父级评论内容 */
    @property(copy,nonatomic)  NSString *parentUserId;/** 父级评论用户编
    @property(copy,nonatomic)  NSString *parentUsername;/** 父级评论用户名称,若为空,无父级评论 */
    @property(strong,nonatomic,readonly) NSMutableArray *linkRangesForParentContent;//保存链接或者评论的地方
    @end
    
    
    .m文件
    @interface LRComment()
    //保存链接或者评论的地方
    @property(strong,nonatomic) NSMutableArray *linkRangesForParentContent;
    @end
    

    封装代码,封装view,封装model,封装一切可能封装的东西

    项目中大量存在着代码冗余代码copy,导致了项目的臃肿

    • list列表大量的headerView动画组加载代码
    • 制作一些控制器的时候,会用到view,但是绝大多数都没封装,被人有相同的view,只能重写一个
    • 未读消息数view没有封装。导致了未读消息树,有的时候使用了我封装的SEBadgeButton,有的时候使用了系统自带的badge,有的时候使用了label,有的使用是用UIImageView.基本每次都要复制一样的代码,及其不统一,修改颜色的时候,及其复杂!!!
    • cell的封装,应该暴露一个对象出来,当传递对象之后,然后更新UI和更新布局,越简单越好.
    • 还有很多,想不起来了...

    //有问题的封装,和不封装没有任何区别

    #import <UIKit/UIKit.h>
    @interface LRMineTableCell : UITableViewCell
    @property (weak, nonatomic) IBOutlet UIImageView *iconImage;
    @property (weak, nonatomic) IBOutlet UILabel *leftlabel;
    @property (weak, nonatomic) IBOutlet UILabel *rightLabel;
    @property (weak, nonatomic) IBOutlet UIImageView *lineImage;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *rightLabelTrailing;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *lineImageLeading;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *lineImageTrailing;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftIconleading;
    @end
    
    #import "LRMineTableCell.h"
    @implementation LRMineTableCell
    - (void)awakeFromNib {
        [super awakeFromNib];
        if(iPhone6P){
            self.rightLabelTrailing.constant = self.lineImageLeading.constant = self.lineImageTrailing.constant = 10;
        }
    }
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
        [super setSelected:selected animated:animated];
        // Configure the view for the selected state
    }
    @end
    
    
    //实际的使用过程
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        if(!self.userId){
            //我的
            LRMineTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LRMineTableCell"];
            if (!cell) {
                cell = [[LRMineTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"LRMineTableCell"];
            }
            
            [cell.iconImage setImage:[UIImage imageNamed:[NSString stringWithFormat:@"MineListIcon%ld",(long)indexPath.row]]];
            cell.leftlabel.text = [self.leftStrArray objectAtIndex:indexPath.row];
            
            cell.lineImage.hidden = cell.rightLabel.hidden = YES;
            
            switch (indexPath.row) {
                case 0:
                {
                    //消息
                    cell.lineImage.hidden = NO;
                    
                    int messageNumber = [[GXTools getUnreadOnlyMessageCount] intValue];
                    if(messageNumber>0){
                        for(UIView *view in cell.subviews){
                            if(view.tag==1001){
                                [view removeFromSuperview];
                            }
                        }
                        UIImageView *numberBG = [[UIImageView alloc] initWithImage:[UIImage imageNamed:messageNumber>=10?@"MineMessageNumberBG2":@"MineMessageNumberBG1"]];
                        
                        UILabel *messageNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, numberBG.image.size.width, numberBG.image.size.height)];
                        messageNumberLabel.backgroundColor = [UIColor clearColor];
                        messageNumberLabel.textColor = [UIColor whiteColor];
                        messageNumberLabel.textAlignment = NSTextAlignmentCenter;
                        messageNumberLabel.font = LR_ANC_FONT(12);
                        messageNumberLabel.text = messageNumber>99?@"⋅⋅⋅":[NSString stringWithFormat:@"%d",messageNumber];
                        
                        [numberBG setFrame:CGRectMake(cell.width-30-numberBG.image.size.width, (cell.height-numberBG.image.size.height)/2, numberBG.image.size.width, numberBG.image.size.height)];
                        numberBG.tag = 1001;
                        [numberBG addSubview:messageNumberLabel];
                        [cell addSubview:numberBG];
                    }else{
                        for(UIView *view in cell.subviews){
                            if(view.tag==1001){
                                [view removeFromSuperview];
                            }
                        }
                    }
                }
                    break;
                case 1:
                    //好友
                {
                    int applyCount = [[GXTools getAsynchronousWithKey:UD_KEY_FRIEND_APPLY_COUNT] intValue];
                    if(applyCount>0){
                        for(UIView *view in cell.subviews){
                            if(view.tag==1002){
                                [view removeFromSuperview];
                            }
                        }
                        UIImageView *numberBG = [[UIImageView alloc] initWithImage:[UIImage imageNamed:applyCount>=10?@"MineMessageNumberBG2":@"MineMessageNumberBG1"]];
                        UILabel *applyNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, numberBG.image.size.width, numberBG.image.size.height)];
                        applyNumberLabel.backgroundColor = [UIColor clearColor];
                        applyNumberLabel.textColor = [UIColor whiteColor];
                        applyNumberLabel.textAlignment = NSTextAlignmentCenter;
                        applyNumberLabel.font = LR_ANC_FONT(12);
                        applyNumberLabel.text = applyCount>99?@"⋅⋅⋅":[NSString stringWithFormat:@"%d",applyCount];
                        [numberBG setFrame:CGRectMake(cell.width-30-numberBG.image.size.width, (cell.height-numberBG.image.size.height)/2, numberBG.image.size.width, numberBG.image.size.height)];
                        numberBG.tag = 1002;
                        [numberBG addSubview:applyNumberLabel];
                        [cell addSubview:numberBG];
                    }else{
                        for(UIView *view in cell.subviews){
                            if(view.tag==1002){
                                [view removeFromSuperview];
                            }
                        }
                    }
                }
                    break;
    
    

    ///正确的写法

    import UIKit
    let LRInteractCellIndentifier = "LRInteractCellIndentifier"
    class LRInteractCell: UITableViewCell {
    
        public class func interactCellWithTableView(_ tableView:UITableView) -> LRInteractCell{
           var cell = tableView.dequeueReusableCell(withIdentifier: LRInteractCellIndentifier)
            if cell == nil{
              cell = LRInteractCell.init(style: .default, reuseIdentifier: LRTopicCellIdentifier)
            }
            return cell as! LRInteractCell
        }
        
        //更新数据
        public var interactF:LRInteractFrame?{
            didSet{
                replyView.interactF = interactF
                beFeedStatusView.interactF = interactF
            }
        }
        
        fileprivate lazy var replyView:LRReplyView = {
             let rv = LRReplyView()
            
            return rv
        }()
        
        fileprivate lazy var beFeedStatusView:LRBeFeedStatusView = {
            let bfsv = LRBeFeedStatusView()
            return bfsv
        }()
        
        override init(style: UITableViewCellStyle, reuseIdentifier: String?){
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            setupBasicUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder:aDecoder)
            setupBasicUI()
        }
        
        fileprivate func setupBasicUI(){
            self.selectionStyle = .none
            isUserInteractionEnabled = true
            contentView.isUserInteractionEnabled = true
            contentView.addSubview(replyView)
            contentView.addSubview(beFeedStatusView)
        }
        
        //绘制一个分割线
        override func draw(_ rect: CGRect) {
            super.draw(rect)
            
            let ctx = UIGraphicsGetCurrentContext()
            
            ctx?.move(to: CGPoint.init(x:LRCommonMargin15,y:height))
            ctx?.addLine(to: CGPoint.init(x:LRScreenWidth-LRCommonMargin15,y:height))
            LRColorSepLineGray.set()
            ctx?.setLineWidth(1)
            ctx?.strokePath()
        }
    }
    
    //外界使用过程,直接给VC减轻负担
        //cell
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = LRInteractCell.interactCellWithTableView(tableView)
        let cmtFrame = listModels[indexPath.row] as! LRInteractFrame
        cell.interactF = cmtFrame
        return cell
    }
    

    解决:写的时候问问同事在项目中有无该控件,如果有,直接使用,如果没有,自己分装,然后在小群里说一下,让大家知道,避免重复分装


    分类名称的写法

    分类分为写框架普通项目
    普通项目,建议直接写名称为UIView+LRExtension
    应该创建一个文件夹,专门存储分类


    view的高度写成常量

    view如果外界需要他,建议写成一个常量,将来直接使用,好处在于,可以统一调控,很多赋值的界面还是有问题的。OC的话,可以使用extern关键字

    供外界使用,要写LR项目前缀,SE是我之前项目的前缀
    自己view使用的,直接使用kLR即可,具体要写清楚是修饰什么东西的.

    #import <UIKit/UIKit.h>
    extern CGFloat const SEBadgeButtonHeight;
    @interface SEBadgeButton : UIButton
    @property (nonatomic, copy) NSString *badgeValue;
    @property (nonatomic, assign) CGFloat badgeWidth;
    @end
    
    #import "SEBadgeButton.h"
    #import "NSString+LRExtension.h"
    CGFloat const SEBadgeButtonHeight = 100.0;
    static CGFloat const kSEBadgeTitleHeight = 44.0;
    @interface SEBadgeButton()
    
    @end
    
    

    使用storyboard

    尽量不要是用sb,非要使用sb的话,复杂的页面避免使用sb,sb应该和控制器放在一起,不能将所有的页面全部都一个sb钟,这样牵一发动全身
    现在项目中的sb都是一个main非常的不便利,导致了冲突时长发生,而且好多界面都是sb出的,修改起来非常的复杂,给别人带来了不变。所以尽量少用sb.


    三个及以上的变量必须要换行,代码的大小写统一

    //这个是正确的,但是我们项目中,matchType的位置很多都写成了MatchType首字母大写了。这个是不对的。还有,超过了3个参数,就应该在调用和声明的时候,换行,过去我认为没有必要,但是看了别人的代码之后,又会不舒服,所以自己就改了

    //函数
    /**
     *  已完成比赛
     *
     *  @param index     第几页
     *  @param matchType 比赛的类别 (有两个常量)
     *  @param ntrpRange 等级
     *  @param timestamp 时间戳
     */
    - (void)fetchCompletedMatchListWithPageIndex:(NSInteger)index
                                       matchType:(NSString *)matchType
                                       ntrpRange:(CGFloat)ntrpRange       //等级
                                       timestamp:(NSString *)timestamp
                                         Success:(FetchDataSourceModelSuccessBlock)success
                                         failure:(CustomFailureBlock)failure;
    

    .view.frame = CGRect.init(x:lx,y:ly,width:lW,height:lH)的写法

    这个要注意,一共要两点

    • 1.换行
    • 2.避免计算在init中,看着费事

    //不好的方法

    _datePicker.frame = CGRectMake(0, kHeight-kPickerHeight, kWidth, kPickerHeight);
    _datePickerToolbar.frame = CGRectMake(0, _datePicker.frame.origin.y - kPickerToolBarHeight, kWidth, kPickerToolBarHeight);
    

    //提出来,可以不用换行也行

        CGFloat commonMargin = 15;
        //1.头像
        CGFloat hX = commonMargin;
        CGFloat hY = commonMargin;
        CGFloat hW = 40;
        CGFloat hH = hW;
        _headIconF = CGRectMake(hX, hY, hW, hH);
        //2.名字
        UIFont *nameFont = [[UIFont alloc] initWithSize:13 type:LRFontTypePingFang];
        CGFloat nX = commonMargin + CGRectGetMaxX(_headIconF);
        CGFloat nY = 19;
        CGFloat nW = [interact.userName calculateTextSizeWithTextFont:nameFont].width;
        CGFloat nH = commonMargin;
        _nameF = CGRectMake(nX, nY, nW, nH);
    

    使用胖model给控制器减肥,暴露出一个属性,可以让大家减少重复的计算

    使用胖model,减少数据的重复计算,既可以减少控制器的压力,还能分装代码,一举两得.
    更具不同的情况,我们要注意重写他们的set或者get方法.

    - (void)setShareData:(LRShare *)shareData{
        _shareData = shareData;
        //在这里计算一下所有的text
        NSString *tmpDistance = [GXTools twoDecimalPlacesFromDouleValue:[NSString stringWithFormat:@"%f",shareData.distance/1000.000]];
        _shareData.distanceText = [NSString stringWithFormat:@"%@km",tmpDistance];
        _shareData.durationText = [GXTools timeFormatFromSeconds:(int)shareData.duration];
        _shareData.speedText = [GXTools speedFormatWithSpeed:shareData.speed];
    }
    
    //这个位置,应该在整个字典转模型结束去做。写get虽然只会去计算一次,但是也会阻塞主线程,将来再去优化代码
    - (NSAttributedString *)beFeedAttriText{
        if (_beFeedAttriText == nil){
            
            //应该判断一下是不是需要的类型,如果是需要的类型,那么我们才去计算数据
            if (_shareType == LRShareSourceHistory
                || _shareType == LRShareSourceLink
                || _shareType == LRShareSourceScoreList
                || _shareType == LRShareSourceRank)
            {
                return nil;
            }
            
            NSString *feedUserName = _feedUserName;
            NSString *feedCnt = nil;   //origin的内容
            if (_feedContent == nil || _feedContent.length == 0){
               feedCnt = @"上传了一张图片";
            }else{
                feedCnt = _feedContent;
            }
            
            //构建出一个 name(橙色):content(灰色)的富文本
            NSMutableAttributedString *presentAttriText = [self appendPresentAttriTextWithFeedUserName:feedUserName
                                                                                           feedContent:feedCnt];
            
            //高亮连接
            presentAttriText = [self highlightLinksWithPresentAttriText:presentAttriText];
            
            //高亮主题
            presentAttriText = [self highlightTopicNameWithPresentAttriText:presentAttriText];
            _beFeedAttriText = presentAttriText;
            
            //计算文字的size
            _beFeedAttrTextSize = [self calculateTextWithPresentAttriText:presentAttriText];
            
        }
        return _beFeedAttriText;
    }
    
    
    

    不要去修改牛逼的第三方。sd,afn 我们项目有修改的情况,消耗性能

    项目中的AFNSDWebImage这些库,影响这很多空间,所以不可以去修改,但是可以写某些分类,减少对整个项目的影响。

    - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
        [self sd_cancelCurrentImageLoad];
        
        if ([url.absoluteString containsString:@"profile/avatar?"]) {
            
            NSString *baseUrl;
            if([[GXTools getAsynchronousWithKey:UD_KEY_AUDIT_USER_NAME] isEqualToString:@"15811281972"]){
                baseUrl = @"http://123.56.228.13:8080/api/v1/";
            }else{
                baseUrl = BASE_URL;
            }
            
            NSURL *cookieHost = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",baseUrl,@"profile/avatar"]];
            NSDictionary *dic = @{@"user_id":[GXTools getAsynchronousWithKey:UD_KEY_USER_ID],
                                  @"token":[GXTools getAsynchronousWithKey:UD_KEY_USER_TOKEN]};
            // 设定 cookie
            [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
                NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                                        [NSDictionary dictionaryWithObjectsAndKeys:
                                         [cookieHost host], NSHTTPCookieDomain,
                                         [cookieHost path], NSHTTPCookiePath,
                                         key,NSHTTPCookieName,
                                         obj,NSHTTPCookieValue,
                                         nil]];
                [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
            }];
            
        }
        
        objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
        if (!(options & SDWebImageDelayPlaceholder)) {
            dispatch_main_async_safe(^{
                self.image = placeholder;
            });
        }
    

    不要无用的打印

    减少无用的打印,尽量保证打印栏目中的干净,调试完数据之后,及时关闭,因为影响心情和消耗性能.
    可以使用LRLog代替,但是网络的打印不应该全都打印出来,这个非常的不好,现在的项目中控制台永远都不会停止!!!


    Block的写法

    请使用SDWebImage的写,有前缀.并且要宏定义一下。然后这样可以将所
    LRNoParaBlock
    Swift中用Close结尾
    不要重复写东西,要去看看之前有无写,即使自己写,也要按照标准,少用int,应该使用NSInteger


    图片的命名

    1.小写+下划线.说明白具体做什么的。因为图片的命名通常很长,使用小写+下划线能区分出来loc和功能
    2.放到文件夹中,并且文件夹的名称用驼峰命名

    所属页面(或模块)+干啥的+(状态情况,可有可无)

    [图片上传失败...(image-c96047-1509616761160)]

    [图片上传失败...(image-4d0db0-1509616761160)]
    [图片上传失败...(image-161ef1-1509616761160)]


    指定一些颜色,字体,等宏定义

    (过去认为没有必要,但是后来发现真的很有必要,统一调控),已于调控,而不是每个位置都写,这样非常的方便。最好等号对其。如果是全局的,那么最好带上前缀,因为在项目中和很多第三方中,宽度的统一是用了kWidth.都有报错重复。
    很多人写项目不喜欢用前缀,是因为将来好放到其他项目中,但是在当前的项目中,看着就特别的不舒服.

    let LRFontHKRegularSize13 = UIFont.init(size: 13, type: LRFontType.hkRegular)
    let LRFontHKRegularSize14 = UIFont.init(size: 14, type: LRFontType.hkRegular)
    let LRFontHKRegularSize15 = UIFont.init(size: 15, type: LRFontType.hkRegular)
    let LRFontHKRegularSize17 = UIFont.init(size: 17, type: LRFontType.hkRegular)
    
    
    //MARK: - 颜色
    let LRColorGray33       = UIColor(gray:33)
    let LRColorGray74       = UIColor(gray:74)
    let LRColorGray165      = UIColor(gray:165)
    let LRColorGray204      = UIColor(gray:204)
    let LRColorGray232      = UIColor(gray:232)
    let LRColorGray246      = UIColor(gray:246)
    let LRColorLightOrangeAlphaHalf   = UIColor.r(r: 255, g: 165, b: 0,alpha:0.5)//常用的文字橙色半透明
    let LRColorSepLineGray            = UIColor.colorFromHex(hexValue: 0xeaeaea)//常用的cell分割线灰色
    let LRColorAlphaBlackSwift        = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)//透明的颜色
    
    
    public let LRScreenWidth:  CGFloat = UIScreen.main.bounds.size.width
    public let LRScreenHeight: CGFloat = UIScreen.main.bounds.size.height
    public let LRScreenBounds: CGRect = UIScreen.main.bounds
    public let LRCommonMargin15:CGFloat = 15.0
    public let LRCommonMargin10:CGFloat = 10.0
    

    给控制器瘦身

    不要将所有的东西都放到控制器中,代码冗余,还有就是好几千行,不封装等等问题。给别人修改造成了困扰

    • 1.控制器写方法啥的都要统一,handleXXXX,遵循一套命名的标准规范和顺序 参考文档
    • 2.使用胖model,减少代码的重复计算啥的
    • 3.分装代码,将和控制器无用的逻辑给不同的view,高度分装。尤其是cell,别封装和不分装似的,没有任何作用。
    • 4.代码相同,可以写基类,有利于代码复用
    • 5.写工具类,将加工的方法放到工具类中,然后减少垃圾代码的产生
    • 6.没事多重构代码,将过去的代码没那么完美,总会有优化的地方
    • 7.more...

    属性的写法,nonamaticstrongreadonly

    这个一般会写的比较乱,是因为三者的顺序乱,没有约定

    我当时也没有去做处理。所以比较乱

    /** befeedStatus富文本属性*/
    @property(strong,nonatomic) NSAttributedString *beFeedAttriText;
    /** 文字的size*/
    @property(assign,nonatomic)  CGSize beFeedAttrTextSize;
    /** 评论的东西(为了给他行间距) */
    @property(strong,nonatomic) NSAttributedString *attriContent;
    /** 文字的size*/
    @property(assign,nonatomic)  CGSize attriContentSize;
    /** 判断是什么类型的*/
    @property(nonatomic,assign,getter=isInteract,readonly) BOOL interact;
    

    以后的顺序

    • 1.nonamatic
    • 2.strong
    • 3.getter
    • 4.readonly

    特殊代码

    
    //别用这种代码
    - (void)showMine{
        self.hisBackBtn.hidden = self.hisDurationLabel.hidden = self.hisDistanceLabel.hidden = self.hisDistanceBottomLabel.hidden = self.hisDurationBottomLabel.hidden = YES;
        self.mineIcon1.hidden = self.mineIcon2.hidden = self.mineIcon3.hidden = self.mineIconBottom1.hidden = self.mineIconBottom2.hidden = self.mineIconBottom3.hidden = NO;
    }
    - (void)showHis{
        self.hisDurationLabel.hidden = self.hisDistanceLabel.hidden = self.hisDistanceBottomLabel.hidden = self.hisDurationBottomLabel.hidden = NO;
        self.mineIcon1.hidden = self.mineIcon2.hidden = self.mineIcon3.hidden = self.mineIconBottom1.hidden = self.mineIconBottom2.hidden = self.mineIconBottom3.hidden = self.medalNew.hidden = self.bestNew.hidden = YES;
    }
    
    
    
    //应该使用懒加载去处理
    
    - (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
        if(!self.userId){
            return nil;
        }else{
            //他的
            if(self.isFriend){
                return nil;
            }else{
                if(self.feedsArray.count>0){
                    UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kWidth, 57)];
                    footerView.backgroundColor = GXColor(255, 255, 255);
                    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(15, 0, kWidth-30, 1)];
                    lineView.backgroundColor = GXColor(240, 240, 240);
                    [footerView addSubview:lineView];
                    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, kWidth, 17)];
                    label.textColor = GXColor(165, 165, 165);
                    label.font = LRFont(12);
                    label.textAlignment = NSTextAlignmentCenter;
                    label.text = @"加为好友查看全部动态";
                    [footerView addSubview:label];
                    return footerView;
                }else{
                    return nil;
                }
            }
        }
    }
    

    统一控制器和View中必要方法名称及注释
    oc中的代码规范
    工作经验

    相关文章

      网友评论

          本文标题:一点工作经验

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