如果一次性创建多个对象 可以使用下面的方法即使用 字符串来创建一些变量
//根据字符串创建class变量
Class cl = NSClassFromString(str);
//根据class变量创建对象
UIViewController *con = [[cl alloc]init];

Block遍历 速度最快 效率最高的遍历方式 数组的方法
[conArr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//obj 数组的元素 idx 数组的索引 *stop 是否停止遍历
}];

将视图从页面上移除(考虑内存管理)
[self removeFromSuperview];

属性修饰符
//nonatomic 非原子操作 不考虑线程安全 多线程
//atomic 原子操作 考虑线程安全 单线程 默认
//strong 引用计数+1 和MRC下的retain 是一样的 除了字符串 block其它对象 都是用strong
//copy 复制新的对象 通常不可变字符串 NSString block会使用这个属性
//assign 直接赋值/简单赋值 引用计数不变 和ARC下的weak类似 通常修饰基础类型
//在ARC下最好使用strong weak 写retain和assign 也可以
//代理 使用weak/assign
//xib连线的都是weak
//readwrite 默认 读写
//readonly 只读
//getter 重命名get方法
//setter 重命名set方法

解决Block引用问题
__weak typeof(self) weakSelf = self;
_album.block = ^(NSString * photoname){
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf NextPage:photoname];
}
else
return ;
}

懒加载创建/初始化数据
// 重写get方法
//当程序调用该数组的时候,这个数组才被调用 可以节省内存
-(NSMutableArray *)dataArr{
//判断成员变量_dataArr是否为空
if(!_dataArr){
_dataArr = [[NSMutableArray alloc] init];

for (int i = 0 ; i < 10; i++) {
        NSString * str = [NSString stringWithFormat:@"数据%d",i];
        [_dataArr addObject:str];
    }
}
return _dataArr;

}

contentView的使用

[self.contentView addSubview:newView] 一般在对cell的自定义时使用

一个视图控制器上添加多个视图控制器、
若没写下面那句话 则使用了tableView 可能会出现崩溃

[self.mainScroll addSubview:controller.view];
//可以把一个视图控制器上的view添加到另一个视图上
//addChildViewController是UIViewController的方法
//把视图控制器作为self的子视图控制器 self也是个视图控制器
[self addChildViewController:controller];

//刷新UI界面要在主线程中
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});

Bounds和Frame区别

frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)

bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点 ) 若设置了bound的位置 则相对于该view的0,0点的坐标的数值就变成了bound中设置的位置的参数 会影响到子视图的位置 相当于内边距的作用

touch事件的优先级和事件传递
1.
一般情况,当一个手势被绑定到某个view时,并且这个手势的交互触发条件和这个view自身的交互触发条件相同时,此时手势会优先接收触发条件,这样view就不能接收到该触发条件。
但是,对buttuon, textField, textView这样的view时,当在其上绑定手势时,这一类的view会优先接收触发条件,而不会让手势接收该触发条件。
2.
- (void)touchesBegan:(NSSet ) touches withEvent:(UIEvent ) event

  • (void)touchesMoved:(NSSet ) touches withEvent:(UIEvent ) event
  • (void)touchesEnded:(NSSet ) touches withEvent:(UIEvent ) event
  • (void)touchesCancelled:(NSSet ) touches withEvent:(UIEvent ) event

上面三个方法就会显示触摸的地方,可以在里面进行响应的操作

touch事件同时只能给一个对象,那么控制touch事件分配的对象也是一个难点了

首先touch事件响应的优先级就是界面的层次,在最上层不响应的时候就会传递给下层

当点击一个区域,想把想把事件传递下去,其他区域拦截事件的时候又是一个问题了

  • (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

这个方法可以很好的解决问题,当返回NO的时候就可以传递下去,返回YES的时候当前对象接受点击事件

CGRectContainsPoint(CGRectMake(0, 0, 40, 40), point);

经常配合这个方法来判断触摸点是否在CGRect内;

//NSBundle 单例 统一管理当前程序资源的一个类
mycell = [[NSBundle mainBundle] loadNibNamed:@”MyCell” owner:self options:nil][0];

tableView设置当中 可以在dataArr的懒加载中访问数据库查询数据

修改状态栏颜色

//第一种 修改状态栏的颜色 只能在Controller里面写

// self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
//
//第二种修改状态栏颜色 需要结合修改plist文件
// View controller-based status bar appearance
// no
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

自定义控件

继承于UIView 如果在xib中对该View进行操作 实例化的时候 应该使用
 UIView* view =[[NSBundle mainBundle] loadNibNamed:@"HeroInfo" owner:self options:nil]  进行实例化。

一些手动添加的控件 需要数据的时候应该手动调用这些方法

view 的生命周期
- (void)loadView
    载入视图过程中执行代码
- (void)viewDidLoad
    视图载入完成需要执行的代码
- (void)viewDidUnload
    卸载视图代 码

//处理中文 unicode编码
NSString * str = [NSString string];

str = [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

// 在视图控制器中添加这句话 可以防止使用xib构建视图后在TabBar管理下底部部分遮挡的情况
self.edgesForExtendedLayout = UIRectEdgeNone; // 防止底部被TabBar遮挡