编程思维误区

750 阅读5分钟

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

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

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

程序员 常见的思维

良好的意图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”的格式内容 准确!!







2016.12.09

goyohol's essay