IOS开发小知识

1. MJRefresh使用小知识

1. 隐藏下拉刷新的时间Label  

 ```Object-c
MJRefreshHeader *refreshHead = [MJRefreshHeader headerWithRefreshingTarget:target refreshingAction:action];  
refreshHead.lastUpdatedTimeLabel.hidden = YES;
```
2. 上拉加载了所有数据  
    可以选择在尾视图显示加载完成:  

    ```Object-c
    [refreshTableView.mj_footer endRefreshingWithNoMoreData];
    ```
    也可以在加载完成后隐藏上拉加载的视图:

    ```Object-c
    refreshTableView.mj_footer.hidden = YES;
    ``` 

2.cell 初始化

对于tableView或者CollectionView的cell或者item 如果是以注册的方式初始化的话一定是会有的,因此就不需要if(!cell)的方式判空,因为一定是存在的
对于collection的头尾市图方式是一样的 因为其头尾视图也是用注册方式的

3. 属性自动合成存取方法

在我们使用属性时,编译器会自动编写访问这些属性所需要的方法,即“自动合成”.这个过程是编译器在编译期间执行的因此我们看不到这些合成方法。除了添加方法外,编译器还自动向类中添加适当类的实例变量。
我们可以自己更改编译器的变量名字
我们可以自己实现存取方法,如果你实现了一个 那么另外一个还是会由编译器合成。我们也可以用@dynamic关键字来阻止编译器自动合成存取方法.

4. 控制器在被pop后未销毁原因

控制器在被pop后移出栈后会被释放,但有些时候会发现控制器出栈的时候不会调用dealloc方法,归根结底,是因为当前控制器被某个对象强引用了,控制器的引用计数不为0,系统无法帮你释放这部分内存
以下几种原因:
1. 控制器中NSTimer没有被销毁
2. 控制器中的代理不是weak属性
3. 控制器中block的循环引用

但是:比如添加的CAAnimation动画是就算不移除也不会影响的释放的

5.对象设置属性的KVC

[self setValue:obj forKey:propertyKey];

6. frame、bounds、center、anchor、transform 关系:

-(CGRect) frame  
{  
     float x = center.x - layer.anchorPoint.x * bounds.width;   
     float y = center.y - layer.anchorPoint.y * bounds.height;  
     float width = bounds.width;
     float height = bounds.height;  
     return CGRectMake(x, y, width, height);
}

-(void) setFrame:(CGRect) rect
{
    center.x = rect.x + layer.anchorPoint.x * rect.width;
    center.y = rect.y + layer.anchorPoint.y * rect.height;
    bounds.width = rect.width;
    bounds.height = rect.height;
}

layer的position和 UIVIew的center是等效的 任何时候都是相等的

所以当我们设置anchor为(0.0)因为bounds没变 center没变 因此frame会变化 而且center出现在左上角

注意
当一个view的transform被更改了,即不为CGAffineTransformIdentity。
frame属性可能会更改,view的bounds,center不会变,layer的position不会变。这个很重要,这样保持了在transform后,view的frame虽然改变了,但是内部参考系是不变的,可以继续进行其他变换,只要不更改frame或center或layer的position。

7.隐藏Tabbar

8. 改变cell点击效果

1.这只是改变点击的颜色 点击效果还在(比如cell上的view颜色消失,image动画暂停)

cell.selectedBackgroundView = [[UIView alloc] initWithFrame:self.frame] ;
cell.selectedBackgroundView.backgroundColor = [UIColor grayColor];

2.这个方法直接关闭了系统的点击效果 自己设计了cell的点击背景颜色变化

cell.selectionStyle = UITableViewCellSelectionStyleNone;

//重写cell的点击高亮
//bgView是我们铺满在cell.contentView上的最后的view
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];
    if (highlighted) {
        [UIView animateWithDuration:0.25 animations:^{
            self.contentBgView.backgroundColor = ICColorOfBorder_Gray;
        }];
    } else {
        [UIView animateWithDuration:0.25 animations:^{
            self.contentBgView.backgroundColor = [UIColor whiteColor];
        }];
        
    }
}

9.强制cell不复用

有时候我们列表中有一个或很少几个cell 是特殊样式 我们并不想它参与cell的复用

UITableViewCell *cell;
//不复用的cell
//这样强制性初始化一个cell 不参与复用
cell = [[UITableViewCell alloc] init];
//参与复用的
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}

10.isKindOfClass && isMemberOfClass

对于我们自定义的继承自UInavigaiton的自定义Navigaition类初始化的对象 并不能用ismemberof判断是不是UINavigation的子类 可以用 iskindof

11.present视图控制器 && 透明控制器

12.tableView reload 引起的复用 不会再次初始化

当tableView的cell有复用并且已经初始化后,再次reloadData这个tableView并不会引起cell重新初始化

13.Timer未移除引起的问题

如果是是视图控制器的timer未移除 这个视图控制器不会被销毁
如果是视图的timer 这个控制器被销毁这个试图都不会被销毁

14.设置按钮disable状态下和平常状态图片相同

[self.confimButton setAdjustsImageWhenDisabled:YES]

15.awakeFromNib

awakeFromNib是nib文件加载完成执行 就是loadFromNib执行完成后执行,而不是在nib文件即将呈现时执行

16.tableView

//动画改变tableView
[self.tableView beginUpdates];  
[self.tableView setTableHeaderView:headerView];  
[self.tableView endUpdates];  

17.textView

textView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);

18.判断字典是否包含某个键

直接对这个字典取这个值 objectForKey 或者 dic[key] 对取出来的值判空即可
但是要保证这确实是一个字典

19.oc中字符串与整型装换

在OC中想将字符串转为整形不能(int)string这样强制类型装换 这样会得到一个很大的无意义值,应该用string.intValue这样的形式 这样的话对于@“123”这样的字符串可以获得整型123,而对于“qed”等不能转转为整形的得到为0

同理,想将整形转为字符串也不能用(NSString *)int(这种形式也是不允许的将整形转为指针?) 这样强转的形式,或得到我们意想不到结果,我们可以用@(int).stringValue形式

20.控制器present问题

对于present出来的控制器
例如 A present B , 然后 B present C ,这时候我们直接对B执行dismiss时没有问题的 不会导致崩溃 只会致使B和C均消失

21.UIButton 扩展

button添加事件可以传递event参数,我们可以通过这个参数传递很多信息(比如点击位置)
[speakBtn addTarget:self action:@selector(speakBtnDragged:withEvent:) forControlEvents:UIControlEventTouchDragOutside];

22.权限服务

当改变应用的 通讯录 照片 相机权限 时会导致应用从新launch

而改变应用或者手机定位权限时不会使应用状态改变

23.label高亮颜色

// the 'highlight' property is used by subclasses for such things as pressed states. it's useful to make it part of the base class as a user property

@property(nullable, nonatomic,strong) UIColor *highlightedTextColor; // default is nil

24.imageView内容是会超出iamgeView的

设置imageViewcontentMode
除了UIViewContentModeScaleToFillUIViewContentModeScaleAspectFit
其他mode会超出边
需要self.iamgeView.layer.masksToBounds = YES;进行裁剪

25.对象是存放在堆中 变量名存放在栈中

初始化一个对象 对象是放在堆中的

26.@synthesize

@synthesize age = _age;

  • 会创造一个带下划线前缀的实例变量名,同时使用这个属性生成getter 和 setter 方法

  • 实际上它的作用是告诉编译器age属性为_age实例变量生成setter and getter方法的实现

  • 也就是说age属性的setter方法是setAge,它操作的是_age这个变量。

如果要阻止自动合成,记得使用 @dynamic 。经典的使用场景是你知道已经在某处实现了getter/setter 方法,而编译器不知道的情况