iOS 开发中需要注意的小地方

/** 图片长度截取方法 */
- (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect )rect{
    CGImageRef sourceImageRef = [image CGImage];
    
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    return newImage;
}



SDWebImage清除缓存
#warning 注意: 清除缓存 清除缓存,一般这个清除缓存,在用户的设置里面进行操作. 如果缓存清除了.虽然减少了内存空间.但是,用户就要再请求一边,这样会费流量啊.
     [[SDImageCache sharedImageCache] clearDisk];//清除缓存



CollecttionView
#warning 注意:布局子视图方法
//优势
// layoutAttributes可以获取到当前cell的信息
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
#warning  注意 层级关系...要是先添加imv 的话 我的lable 就被档下去了,文字就不见了
    _lable.frame = CGRectMake(0, layoutAttributes.frame.size.height - 30, layoutAttributes.frame.size.width, 30);
    _lable.backgroundColor = [UIColor blackColor];
    _lable.textColor = [UIColor whiteColor];
    _lable.textAlignment = NSTextAlignmentCenter;
    _lable.alpha = 0.33;
    
    
    _imv.frame = CGRectMake(0, 0, layoutAttributes.frame.size.width, layoutAttributes.frame.size.height);
    
    

}

#warning 注意MRC情况下 set的写法
- (void)setModel:(Model *)model
{
    if (_model != model) {
        [_model release];
        _model = [model retain];
        //赋值
        self.lable.text = [NSString stringWithFormat:@"%@",model.height];
        [self.imv sd_setImageWithURL:[NSURL URLWithString:model.thumbURL] placeholderImage:[UIImage imageNamed:@"placeHoderImage"]];
    }
}



字符串
#warning 这个比较新鲜, 中文转码(如果网址中有中文,需要中文转码)
//赛选中文 / 中文转码
    NSString *newStr = [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:str]];

+ (void)musicModelRequest:(MusicModel *)model{
    NSString *str = model.lyric;
#warning 拆分字符串,放到数组中
    NSArray *array = [str componentsSeparatedByString:@"
"]; //见到/n就把这个字符串放到数组中
 
    //区分时间与歌词
    NSMutableArray *timeMutableArray = [NSMutableArray array]; //接收时间
    NSMutableArray *lyricMutableArray = [NSMutableArray array]; //接收歌词
    
    for (NSString *string in array) {
        
        NSArray *timeAndLyric = [string componentsSeparatedByString:@"]"];//拆分时间与歌词
        [lyricMutableArray addObject:timeAndLyric.lastObject];
        
       
        NSArray *timeArray = [timeAndLyric.firstObject componentsSeparatedByString:@"["];//拆分时间
        [timeMutableArray addObject:timeArray.lastObject];
        
            }
    
    //赋值
    model.timeArray = [NSArray arrayWithArray:timeMutableArray];
    model.lyricArray = [NSArray arrayWithArray:lyricMutableArray];
    
    
    
}



XIB StorryBorad可视化
#warning 注意: View创建方法...
- (void)loadView
{
    //参数1要加载的XIB文件  参数2文件拥有者   参数3加载选项
    self.htView = [[NSBundle mainBundle] loadNibNamed:@"HTView" owner:self options:nil].firstObject;
    self.view = _htView;
}

#warning 注意: View改文字改属性,在这儿
#import "TextView.h"

@implementation TextView


//改文字,改属性在这儿
- (void)awakeFromNib
{

    self.titleLable.text = @"改文字,改属性在这儿";
}




@end

 #warning 注意:Cell注册.....   
//注册
//    [self.tableView registerClass:[SecondViewController class] forCellReuseIdentifier:cell_id_Second];
    [self.tableView registerNib:[UINib nibWithNibName:@"SecondTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:cell_id_Second];

#warning 注意:使用storyBoard关联的类不再使用init方法创建,直接去storyBorad里面找有当前标识符的视图控制器的拖放面板.
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{


    UIStoryboard *st = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];//1、先去当前包里找到故事版
    
    TextViewController *textVC = [st  instantiateViewControllerWithIdentifier:@"testViewController"];//2、根据标示符,在故事版中找到当前视图控制器
    
    [self.navigationController pushViewController:textVC animated:YES];
    

}

#warning 获取路径
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSIndexPath *path = [self.tableView indexPathForCell:sender]; //获取路径。。。。。  关键呀.******************************************************
    
    DetailViewController *detal = segue.destinationViewController;
    detal.string = _array[path.row];
}





TabBar
#warning 图片这块注意:@2x作用,系统自动匹配大小.

#warning  PUS后 隐藏TabBar
- (void)buttonAction:(UIButton *)sender
{
    TextViewController *text = [[[TextViewController alloc] init] autorelease];
    text.hidesBottomBarWhenPushed = YES;PUS页面的时候隐藏tabBar
    [self.navigationController pushViewController:text animated:YES];
//有些应用点击的时候隐藏 导航栏 和 标签栏. 是这样做的
//    self.navigationController.navigationBar.hidden = YES;
//    self.tabBarController.tabBar.hidden = YES;
   //在手势点击事件里设置。根据点击此时,奇偶数进行判断就OK了
}

#pragma mark 当点击标签栏的时候触发此方法
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    if (viewController.tabBarItem.badgeValue != nil) {
        viewController.tabBarItem.badgeValue = nil;
  }
    NSLog(@"%ld",tabBarController.selectedIndex);//输出选中下标,做下演示
}




BLOCK
//MRC销毁
- (void)dealloc
{
#warning block 的释放只能使用Block_release() //系统写好的释放方法
    Block_release(_myBlock); //因为block不是一个对象类型不能使用relese,是函数.
    Block_release(_cBlock);//释放
    [_textField release];
    [super dealloc];
    NSLog(@"验证dealloc成功");
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
#warning //block就是一个回调函数,相当于小弟,什么时候用,什么时候调。 哈哈
    //block(函数) 调用
    _myBlock(_textField.text);
    
    
    
   
    
    
    
#warning  解决循环引用问题    //记住:Block 实现部分不能直接使用属性、实力变量 和 self 去调用; 因为会照成循环引用就是相互持有(不会走dealloc方法),  例如:[self text];这样调用, 错得。循环引用了.
   
//////////解决循环引用问题演示:
//MRC:
    //第一种写法
    __block SecondViewController *temp = self;

   //第二种写法:
    //__block typeof(self) temp = self;
    
//ARC:
    
    //__weak SecondViewController *temp = self;
    
//实现
    self.cBlock = ^(){
       [temp text];
   };
   
//调用
    temp.cBlock();
   [self.navigationController popViewControllerAnimated:YES];
}

#import <UIKit/UIKit.h>
typedef void(^MyBlock) (NSString *); //定义有参,无返回值的匿名函数传递字符串; 这是函数
typedef void (^Block)(); //做内存测试


@interface SecondViewController : UIViewController


@property(nonatomic,retain)UITextField *textField;

//MRC: block的语义设置是copy 把block从栈区 拷贝到 堆区 。使用完之后,在dealoc 里面释放.(blcok是函数,函数在栈区)
//ARC:block的语义设置使用strong 即可
@property(nonatomic,copy)MyBlock myBlock; //参数 函数

@property(nonatomic,copy)Block cBlock;

@end



单例
#warning 单例
//创建静态区对象的原因:希望程序运行期间它在程序中一直存在,这样对外界来说,可以随时读取数据.
//我们创建单例使用加号方法的原因是因为:在创建之前,无法存在一个实例对象去调用动态方法来创建它本身
/////劣势:创建多了,会影响性能,内存空间减小。程序会卡.因为是在停留静态区。生命周期,与程序同步。
/////优势:降低耦合性,降低复杂性; 可以全局访问 ;在内存中只有一个对象,节省内存空间;避免频繁的创建销毁对象,提高性能;避免对共享资源的多重占用.

//完整单例手写吧
//+ (instancetype)sharedDaraHandle
//{
//    static DataHandle *dataHandle = nil;
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        
//        dataHandle = [[DataHandle alloc] init];
//        
//    });
//    
//    return dataHandle;
//}


文本高度自适应 + 图片高度自适应 + Cell注意事项
//heightForRowAtIndexPath 这个方法会比cellForRowAtIndexPath先执行,所以我们需要先计算好cell高度,
#warning 注意:注意:注意:只有cell要在layoutSubViews里面布局,因为这个方法最后走,cell需要重用.所以在这里布局.
#warning  注意:最后走这个方法, 还有 图片自适应及文本自适应! 以及layoutSubviews方法里self的宽 和 高 与 初始化里面的不同.
//最后走这个方法
- (void)layoutSubviews
{
    [super layoutSubviews];
#warning 注意:注意:注意:这里千万不能这样赋值   _lable.frame = self.frame 要这样_lable.frame = self.contentView.frame
#warning 注意:注意:注意:这里千万不能这样赋值   _lable.frame = self.frame  要这样_lable.frame = self.contentView.frame
#warning 注意:注意:注意:这里千万不能这样赋值   _lable.frame = self.frame  要这样_lable.frame = self.contentView.frame
 
//图片高度自适应
    CGFloat height = self.imv.image.size.height * self.contentView.frame.size.width / self.imv.image.size.width;
    self.imv.frame = CGRectMake(0, 0, self.contentView.frame.size.width, height);
    self.imv.backgroundColor = [UIColor grayColor];
    
    
   //lable高度自适应

    CGFloat lableHeight = [self myHeight:self.lable.text];
    self.lable.frame = CGRectMake(0, height, self.contentView.frame.size.width, lableHeight);
    self.lable.backgroundColor = [UIColor orangeColor];
    self.lable.numberOfLines = 0;
    self.lable.font = [UIFont systemFontOfSize:17];

    NSLog(@"--------W:%lf  H:%lf",self.frame.size.width,self.frame.size.height);
}

- (CGFloat)myHeight:(NSString *)string
{
    CGRect rect = [string boundingRectWithSize:CGSizeMake(self.frame.size.width, 100000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:17]} context:nil];
    
    return rect.size.height;
}


#warning  UILable和UIImageView 的用户交互,默认是关闭的


懒加载
#pragma mark 懒加载 重写get方法 //原来这也是懒加载,实质就是get方法(懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。)
- (void)addAllViews{
    [self addSubview:self.nameLabel]; //懒加载(用了点语法,才能调用get方法)
    [self addSubview:self.nameTextField]; //懒加载
}
#pragma mark 懒加载 重写get方法
- (UILabel *)nameLabel{
  if (!_nameLabel) {
#warning  注意,创建的时候一定要用self. 点语法创建, 不要_nameLable这样取创建
        self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
        _nameLabel.text = @"懒加载";
   }
   return _nameLabel;
}



#pragma mark 布局子视图
//布局子视图(从新布局view. 此方法,自动触发,程序最后走这个方法)
- (void)layoutSubviews{
//[UIApplication sharedApplication].statusBarOrientation
    //statusBarOrientation状态栏方向(应用程序)
     
    if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft || [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
        [super layoutSubviews];
        _nameTextField.frame = CGRectMake(150, 20, 400, 50);
        _nameTextField.backgroundColor = [UIColor redColor];
        //如果是横屏,XXXX
   
    }else{
        [super layoutSubviews];
        //如果是竖屏,XXXX
        _nameTextField.frame = CGRectMake(0, 120, 150, 30);
        _nameTextField.backgroundColor = [UIColor whiteColor];
        
    }
    
  //(这里是根据应用程序的状态栏方向,来从新布局子时视图)
    
}

//此方法,绘图的时候,用
- (void)drawRect:(CGRect)rect {
    // Drawing code  绘图时候用
}
从写Model的Get方法 赋值时, 注意: 在if {} 花括号外边进行.
原文地址:https://www.cnblogs.com/HaiTeng/p/5324130.html