记录日常开发中遇到的小问题和小技巧,后续持续更新中......
-
1 在异步线程中发送通知,那么接收此通知也在异步线程。
-
2 没有实现estimatedHeightForRowAtIndexPath方法时,调用顺序如下:
1、numberOfRowsInSection
2、heightForRowAtIndexPath
3、cellForRowAtIndexPath
如果实现了estimatedHeightForRowAtIndexPath方法,调用顺序如下:
1、numberOfRowsInSection(不变)
2、estimatedHeightForRowAtIndexPath
3、cellForRowAtIndexPath
4、heightForRowAtIndexPath
点击刷新后
- (void)reloadHomeData{
NSLog(@"======开始刷新1");
[self.tableView reloadData];
NSLog(@"======刷新结束5");
}
#pragma mark - UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(@"======numberOfRowsInSection 2");
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"======cellForRowAtIndexPath 3");
oneViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([oneViewCell class])];
cell.model = self.arrData[indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"======heightForRowAtIndexPath 4");
return 60;
}
但是再执行 [self.tableView reloadData];后打印顺序为
2019-07-03 19:14:39.469747+0800 BaseProject[9152:5236446] ======开始刷新1
2019-07-03 19:14:39.470010+0800 BaseProject[9152:5236446] ======numberOfRowsInSection 2
2019-07-03 19:14:39.470187+0800 BaseProject[9152:5236446] ======刷新结束5
2019-07-03 19:14:39.470938+0800 BaseProject[9152:5236446] ======cellForRowAtIndexPath 3
2019-07-03 19:14:39.471754+0800 BaseProject[9152:5236446] ======heightForRowAtIndexPath 4
2019-07-03 19:14:39.472490+0800 BaseProject[9152:5236446] ======cellForRowAtIndexPath 3
2019-07-03 19:14:39.472986+0800 BaseProject[9152:5236446] ======heightForRowAtIndexPath 4
-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用
-layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)
如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局
在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]
所以可以在 [self.tableView reloadData]; 后再调用 [self layoutIfNeeded];
-
4 MVP理解
个人对于MVP思路的理解,就是开发过程中,数据和界面之间的交互,使用Presenter层管理,较于MVC模式:获取数据,构建对象,在控制器里赋值更新界面;MVP模式思路在获取数据,构造对象后,不直接在控制器中做界面交互逻辑,而是使用控制器层管理,将业务逻辑独立出来,这样便于代码的后期维护,同时降低了控制器的负担以及数据模型和控制器、界面之间的耦合性 -
5 查看App 在苹果商店的信息
NSString *url = @"http://itunes.apple.com/cn/lookup?id=你的AppId";可以查询版本等信息,可用于版本判断。 -
6.Runtime的强大在于它能够在程序运行时获取并修改类的各种信息,包括获取某个类的方法列表、属性列表、变量列表,为某个类动态添加方法、属性,修改某个类的方法属性等等;
runtime的应用:
1.动态创建一个类(比如KVO的底层实现)
2.动态地为某个类添加属性\方法, 修改属性值\方法
3.遍历一个类的所有成员变量(属性)\所有方法
实质上,以上的是通过相关方法来获取对象或者类的isa指针来实现的。
简单罗列method相关的函数
//判断类中是否包含某个方法的实现
BOOL class_respondsToSelector(Class cls, SEL sel)
//获取类中的方法列表
Method *class_copyMethodList(Class cls, unsigned int *outCount)
//为类添加新的方法,如果方法该方法已存在则返回NO
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
//替换类中已有方法的实现,如果该方法不存在添加该方法
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
//获取类中的某个实例方法(减号方法)
Method class_getInstanceMethod(Class cls, SEL name)
//获取类中的某个类方法(加号方法)
Method class_getClassMethod(Class cls, SEL name)
//获取类中的方法实现
IMP class_getMethodImplementation(Class cls, SEL name)
//获取类中的方法的实现,该方法的返回值类型为struct
IMP class_getMethodImplementation_stret(Class cls, SEL name)
//获取Method中的SEL
SEL method_getName(Method m)
//获取Method中的IMP
IMP method_getImplementation(Method m)
//获取方法的Type字符串(包含参数类型和返回值类型)
const char *method_getTypeEncoding(Method m)
//获取参数个数
unsigned int method_getNumberOfArguments(Method m)
//获取返回值类型字符串
char *method_copyReturnType(Method m)
//获取方法中第n个参数的Type
char *method_copyArgumentType(Method m, unsigned int index)
//获取Method的描述
struct objc_method_description *method_getDescription(Method m)
//设置Method的IMP
IMP method_setImplementation(Method m, IMP imp)
//替换Method
void method_exchangeImplementations(Method m1, Method m2)
//获取SEL的名称
const char *sel_getName(SEL sel)
//注册一个SEL
SEL sel_registerName(const char *str)
//判断两个SEL对象是否相同
BOOL sel_isEqual(SEL lhs, SEL rhs)
//通过块创建函数指针,block的形式为^ReturnType(id self,参数,...)
IMP imp_implementationWithBlock(id block)
//获取IMP中的block
id imp_getBlock(IMP anImp)
//移出IMP中的block
BOOL imp_removeBlock(IMP anImp)
//调用target对象的sel方法
id objc_msgSend(id target, SEL sel, 参数列表...)
- 设置 UITableView为 UITableViewStyleGrouped 形式,
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight - 64 - 44) style:UITableViewStyleGrouped];
但想改变 组与组之间的间距,可设置如下:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, 38)];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 8;
}
- UILabel 显示富文本效果
NSString *textStringLow = @"djlflfjsdlkfjldkjsjfdfdjskfjds若发现了问题,请在下方选择检查项,否则不选择";
NSString *noteStrLow = @"(若发现了问题,请在下方选择检查项,否则不选择)";
NSRange _range= [textStringLow rangeOfString:noteStrLow];
NSMutableAttributedString *noteString = [[NSMutableAttributedString alloc] initWithString:textStringLow];
if (_range.location != NSNotFound){
NSDictionary *dic = @{NSFontAttributeName :[UIFont fontWithName:@"PingFangSC-Regular" size:14],NSForegroundColorAttributeName:[UIColor colorForHexString:@"999999"]};
[noteString addAttributes:dic range:_range];
}
[label setAttributedText:noteString];
网友评论