编程思维误区

作者: goyohol | 来源:发表于2016-12-09 23:50 被阅读66次


    文章本身意义不大,但是却包含一些趣味性。我自己也工作了一段时间,觉得程序员还是比较容易走入某些误区的!但是蓦然回首,又觉得柳暗花明~~~
    本文主要罗列一些编程上的思维、逻辑,就权当趣味文字来读读就好了~

    陷阱之所以阴险,是因为它让你觉得你自己是在往正确的道路上走。简言之就是,当你做一些你认为应该做的事情时,但却没有用你应该做的方式。
    要始终明白一点:计算机是不会撒谎的!(也可以叫傻瓜,按着它的流程就不会有问题)

    今天太晚了!有点困了!! 之后有空会继续加入~




    程序员 常见的思维

    良好的意图1:优化代码

    陷阱1:过早优化
    陷阱2:过晚优化

    良好的意图2:程序抽象

    陷阱1:过于复杂
    陷阱2:忽视抽象

    良好的意图3:使用编程工具

    陷阱1:“我需要的一切已经有人写好了”
    陷阱2:重新发明轮子 (重新写了很多函数)

    良好的意图4:跨平台

    陷阱1:过度跨平台
    陷阱2:只适用于单一平台 (移动开发 HTML5:跨平台,也比较火)











    数组的陷阱

    //数组创建时  妄想把两数组⭐️合并⭐️在一起就是两个数组的合并(元素个数:两个数组元素个数之和)。
    NSMutableArray * perArr = @[self.peripheralArr,self.reConnectPeripheralMac_Arr].mutablecopy;
    //其实 合成数组只是拥有⭐️两个⭐️“数组元素”的一个数组。
    
    2个 “数组”元素


    改善写法:

    NSMutableArray * perArr = self.peripheralArr.mutableCopy;  
    //变成 和第一个数组的相同 的可变数组
    for (int i = 0; i < self.reConnectPeripheralMac_Arr.count; i ++) {  
    //遍历第二个数组,依次添加数组中的各个元素
        [perArr addObject:self.reConnectPeripherals[i] ];
    }
    
    多个 数组元素





    字符串比较

    if ([compStr compare:@"string"] == NSOrderedSame) {
        // Do thing1
    } else {
        // Do thing2
    }
    

    NSOrderedSame 表示比较的两个字符串完全一致!在枚举中,它的值是 “0”。

    如果当compStr为空的时候,[compStr compare:@"string"] 消息的返回就会为nil。nil表示一个空的Objective-C对象,实际就是表示一个空指针,而它代表的值就是0,与NSOrderedSame的值相等。即如果compStr为nil,那么整个语句的值为真。这会给程序造成非常严重的问题,小则逻辑错误,UI显示错误等,大则会造成数据泄漏等等。


    改善写法:

    if (compStr != nil && [compStr compare:@"string"] == NSOrderedSame) {
        // Do thing1
    } else {
        // Do thing2
    }
    




    无限循环(又叫:死循环)

    无限循环在使用时,要注意一定不能对“参与无限循环”的方法或变量,进行操作。否则会照成恶性循环(真的死循环了)!

    • 1.良性无限循环

      -(void)neverStop {  //根本停不下来
        int a = 0;
        while(a<10)  {
            NSLog(@"更不停不住啊~~~ Value:%d\n",a);
            if( a == 5){ //a设定为5,则把a赋值为0  (进入无穷回圈 打印);
                a = 0;
            }
            a++;
        }
        return;    
      }
      


      在 - (void)viewDidLoad { }里面:

      [self neverStop];
      



      在电脑上CPU使用情况已经如此!!!
      刚开始执行时硬盘写入速度到达了800~900 KB/s。

      电脑上的使用情况

      本人以前实力作死,把这段代码写到手机APP的demo里面,然后手机里面的APP就一直在死循环。。。
      最后还不能关闭(后台运行上没有APP,但是还在运行!!!要关闭两次!第一次好像没管用!) 关闭屏幕再打开,手机也不能选择(多任务查询)查看后台运行状态。
      而且手机一直在🔥🔥🔥升温!!!发烧!!!!!
      最后是:点击同步的那个Safari浏览器,手机才进入可控状态!然后赶紧关闭APP运行状态,然后重新再电脑上运行、安装一次APP。吓死我了~~~~~😂😂😂😂😂
      所以说APP的demo在书写时,一定要慎重处理死循环 (毕竟手机上还不能提示你APP使用内存、占用CPU的状态)。在适当的地方跳出来!!!不然就真成了死循环了!!!!!
      😔哎,现在想想都觉得后怕!!


      手机出问题时 截的图 (因为第一次遇到,当时完全懵逼)


      良性无限循环例子🌰

      呼吸动画
      只有在程序中调用任意一个即可进入无尽的呼吸效果~

      - (void)HighlightAnimation{      // 明亮效果
        __block typeof(self) Self = self;
        [UIView animateWithDuration:1.5f animations:^{    
            Self.backgroundView.backgroundColor = [Self.backgroundView.backgroundColor colorWithAlphaComponent:0.3f];    //变亮 动画(透明度 增加)
        } completion:^(BOOL finished) {
            [Self DarkAnimation];        
        }];
      
      }
      
      
      
      - (void)DarkAnimation{         // 黑暗效果
        __block typeof(self) Self = self;
        [UIView animateWithDuration:1.5f animations:^{  
        Self.backgroundView.backgroundColor = [Self.backgroundView.backgroundColor colorWithAlphaComponent:0.6f];    //变暗 动画
        } completion:^(BOOL finished) {
            [Self HighlightAnimation];  
        }];   
      
      }
      





    • 2.恶性无限(死)循环
      以前做蓝牙设备时,在搜索服务的方法有进行的搜索服务操作。造成了死循环!!手机瞬间就烫了。。也不做操作了,反正很危险。

      无限循环使用时要谨慎!




      恶性无限循环例子🌰
      @interface ViewController () <UITableViewDataSource>
      
      @property (nonatomic,strong) UITableView * tabV;
      
      @end
      


      在“- (void)viewDidLoad { }”里面:

      self.tabV = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/2.f) style:UITableViewStylePlain];
      self.tabV.dataSource = self;
      [self.view addSubview:self.tabV];
      


      UITableView的代理方法:

      #pragma mark - UITableViewDataSource
      -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
          return 100;
      }
      -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
          if (!cell) {
              cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
          }
          [self.tabV reloadData];//⭐️⭐️⭐️自动刷新tableView⭐️⭐️⭐️ 
      
          return cell;
      }
      


      效果:

      瞬间 CPU使用率到99%
      原因分析:UITableView的“[self.tabV reloadData]”方法被响应时,会自动调用“UITableViewDataSource”方法。从而形成了反复调用的“引用环”!!






    可变数组的影响

    @property (nonatomic,strong)NSMutableArray * dataArr;  // 可变数组
    @property (nonatomic,strong)NSString * conditionStr;  // 条件判断字符串
    
            
    // 随意写的数组     (加入 数据)
    self.dataArr = @[@{@"condition":@"a"},
                     @{@"condition":@"b"},
                     @{@"condition":@"a"},
                     @{@"condition":@"d"},
                     @{@"condition":@"a"},
                     @{@"condition":@"e"},
                     @{@"condition":@"a"},
                     @{@"condition":@"e"}].mutableCopy;
    
    
    //【一】 遍历自身(可变数组)            会⭐️改变(影响)自身
    for (int i = 0; i < self.dataArr.count; i ++) {  // 遍历 扫描到的所有
        
       if (![self.conditionStr isEqualToString:self.dataArr[i][@"condition"] ]) {    //不是同类型,移除
            [self.dataArr removeObject:self.dataArr[i] ];// 数组顺序也改变了
        }
    }
    

    每次遍历之后:若移除过元素,会对下一次的遍历 造成影响!

    可变数组 移除 数据(元素)后,再以“for( ; ; )”格式进行遍历时。可变数组 的个数 改变 会影响下一次的遍历。

    更改后的操作:

    //【二】 记录 数组个数,进行 全数(所有个数:⭐️固定⭐️)遍历
    NSInteger all_Num = self.dataArr.count;
    for (int i = 0; i < all_Num; i ++) {  // 遍历 扫描到的所有
        
       if (![self.conditionStr isEqualToString:self.dataArr[i][@"condition"]) {    //不是同类型,移除
            [self.dataArr removeObject:self.dataArr[i] ];// 数组顺序也改变了
        }
    }
    

    依然不对,数组的个数减少(导致 下标改变)!下次遍历依旧不对!


    进行对不可变数组遍历,如下:

    // 【三】转为 对 (相同结构的)不可变数组 的遍历
    NSArray * copy_allArr = self.dataArr.copy;
    for (int i = 0; i < copy_allArr.count; i ++) {  // 遍历 扫描到的所有
        
        if (![self.conditionStr isEqualToString:copy_allArr[i][@"condition"] ]) {    //不是同类型,移除
            [self.dataArr removeObject:copy_allArr[i] ];
        }
    }
    





    感觉自己的编程入门:

    当能解释清楚 “ ‘Hello world’ 被printf到屏幕上”的全过程!


    感觉编程的入门






    化繁为简

    在“-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { }”里面:

    switch (section) {
        case 0:{
            return ((NSArray *)self.dataArr[section]).count;
        }break;
        case 1:{
            return ((NSArray *)self.dataArr[section]).count;
        }break;
        default:{
            return ((NSArray *)self.dataArr[section]).count;
        }break;
    }
    


    等价于:

    return ((NSArray *)self.dataArr[section]).count;
    

    只需要保证“self.dataArr”的格式内容 准确!!





















    goyohol's essay

    相关文章

      网友评论

        本文标题:编程思维误区

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