1、不自定义Cell,利用UITableView的几个属性 做出系统样式的编辑选中
pic-1.jpeg
//1.允许在编辑模式中进行多选操作 self.tableView.allowsSelectionDuringEditing = YES; //2.改变tableView的当前编辑状态 [self.tableView setEditing:!self.tableView.isEditing animated:YES]; //3.获取在编辑状态下被选中的cell NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
2、UITableView容易混淆模糊的属性(驼峰语法看起也头痛^ ~^ !!)
allowsSelectionDuringEditing : 默认NO,编辑模式下是否可以选中
allowsSelection 默认YES,控制在,非编辑模式下row是否可以被选中
allowsMultipleSelection 默认NO,控制tableview是否能同时多行选中
allowsMultipleSelectionDuringEditing 默认NO,控制编辑模式下是否能同时多行选中
3、iOS图片拉伸技巧 代码及storyboard方式
原理: 配置保护哪部分内容,拉伸哪部分
1、传入left和top保护宽度(iOS5之前),系统帮你拉伸1X1
//leftCapWidth代表左端盖宽度,topCapHeight代表顶端盖高度 - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;
2、传入上下左右四个方向需要保护的区域,拉伸不需要保护的地方(iOS)
//UIEdgeInsets类型的参数 内边距 - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
PS:不知道拉伸区域为负数会如何,晚上实验一下
3、iOS6之后的方法。 在上个方法基础上加了伸缩模式:平铺/拉伸
//UIEdgeInsets类型的参数 内边距 //UIImageResizingMode 通过拉伸UIEdgeInsets指定的矩形区域来填充图片 - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode
三种代码方式原理详细见解请看这位作者 iOS图片拉伸原理介绍
4、storyboard在Asset中设置,一劳永逸。配置好就不用代码了
参数配置参考第三条。
storyboard.png
4、iOS图片缩小方法 (show code)
//img:为传入的图片; size:为放置图片区域的大小; scaledImage:为返回压缩后的图片 + (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{ // 创建一个bitmap的context // 并把它设置成为当前正在使用的context UIGraphicsBeginImageContext(size); // 绘制改变大小的图片 [img drawInRect:CGRectMake(0,0, size.width, size.height)]; // 从当前context中创建一个改变大小后的图片 UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext(); // 使当前的context出堆栈 UIGraphicsEndImageContext(); //返回新的改变大小后的图片 return scaledImage; }
5、KVC将字典赋值到模型中
KVC :Key Value Coding 即键值编码,通常是用来给某一个对象的属性进行赋值
[obj setValuesForKeysWithDictionary:(NSDictionary *)];
6、修饰block为什么要用copy delegate要用weak
Block
block是一个对象, 所以block理论上是可以retain/release的. 但是block在创建的时候它的内存是默认是分配在栈(stack)上, 而不是堆(heap)上的. 所以它的作用域仅限创建时候的当前上下文(函数, 方法...), 当你在该作用域外调用该block时, 程序就会崩溃.
在方法中的block创建在栈区, 使用copy就能把他放到堆区, 这样在作用域外调用该block程序就不会崩溃.
Delegate
delegate 要用weak,主要是考虑到循环引用的问题。
如果delegate用强引用。A对象持有B对象,A又作为B对象的代理。两者之间就有两条强引用。A想要释放的时候,B强引用释放不了。B想释放,A又强引用着。造成循环引用。
7、id 与 instancetype 使用区别及举例理解 以及初始化方法为什么不用(ClassName *)返回示例对象
首先instancetype、id都是任意对象类型
instancetype自动识别当前是哪个类在调用,就会变成相应类的对象
id 首先不能使用.语法。
id可以作为方法的参数,但instancetype不可以
id 可以调用任何对象的方法,这样就不利于编译器检查错误
@interface Shop :NSObject +(instancetype)shopWithName:(NSString *)name; ------1 写法 +(id)shopWithName:(NSString *)name; ------2 写法 @end
- (void)viewDidLoad{ [super viewDidLoad]; [[Shop shopWithName] setFrame:CGRectZero]; }
如果shopWithName是1写法 ,编译器就会报错,是2写法 ,编译器就不会报错。
初始化方法为什么不用(ClassName *)返回示例对象呢
原因:比如说一个Animal类,是用+(Animal *)animalWithName:(NSString *)name这种方法书写的便利构造。那么当有一个子类Dog继承于他,没有书写任何东西,像下面这样调用:
- (void)viewDidLoad{ [super viewDidLoad]; //子类可以使用父类非privated的属性和方法 Dog *dog = [[Dog animalWithName]; }
+(Animal *)animalWithName:(NSString *)name返回的是一个Animal对象,你赋值给Dog类实例,系统就会在这儿提出警告说你类型不匹配。
8、KVC系统查找顺序
当调用setValue:属性值 forKey:@”name“的代码时:以@property name为例;
首先查找对象有没有setName,有则调用set方法赋值
没有找到set方法,就查找对象的成员变量有没有_name,有就_name = value
如果没有找到_name,还会去对象中查找name属性
最终没有找到则报错
9、宏及宏定义常见书写介绍
宏里边可变参数:是三个点...
宏定义中的函数的可变参数:__VA_ARGS__
这句话理解就是:__Value_ Arguments__ value:值 Arguments__:参数
举例:
#ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr,"%s/n",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); #else #define NSLog(...) #endif
10、模拟器 模拟内存警告
操作步骤:
一、实现测试内存警告接收方法
//appdelegate.m文件实现应用程序接收内存警告协议方法 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{ NSLog(@"%s",__func__); }
二、模仿内存警告
操作:
1.Debug-》Simulate Memory Warning
samulator.png
11、自定义控制器View
做法:重写控制器的-loadView方法。
- (void)loadView{ self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds]; self.view.backgroundColor = [UIColor redColor]; }
loadView调用时机:第一次使用控制器的View的时候调用。
注意:不要调用[super loadView]方法,你调用了super,还不如不重写
注意:重写方法中如果没有利用自定义view对vc.view重新赋值,那么就不要去获取控制器的view取使用。会造成死循环,原因参照第一条self.view调用时机。如下图:
迭代死循环.jpeg
12、iOS系统自带方法渲染图片
[[UIImage new] imageWithRenderingMode:UIImageRenderingMode];
13、@synchronized互斥锁简介
互斥锁格式:
@synchronized(锁对象){ //需要锁定的代码 }
注意:锁定1份代码只能用一把锁,即唯一的锁对象。用多把锁是无效的
优点:能有效防止多线程抢夺资源造成的数据安全问题
缺点:需要消耗大量的CPU资源
使用前提:多条线程抢夺同一块资源,请且对资源有读写操作,且每个线程的顺序是对结果有影响的情况下使用互斥锁。
假如在面试过程中,问到线程同步的东西,这个互斥锁就是使用了线程同步技术。线程同步的意思就是多条线程在同一条线上执行(按顺序执行任务)
14、挺全面的atomic nonatomic 注解
atomic 的本意是指属性的存取方法是线程安全(thread safe).但不保证整个对象都是线程安全的。比如声明一个atomic修饰的NSMutableArray变量marray,此时self.marray和self.marray = otherarray都是线程安全的。但是使用[self.marray objectAtIndex:index]就不是线程安全的,需要配合其他线程安全技术来保证。
Atomic不能保证对象多线程的安全。所以Atomic 不能保证对象多线程的安全。它只是能保证你访问的时候给你返回一个完好无损的Value而已。举个例子:
如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。
nonatomic:对应的就不考虑线程安全
说明:atomic要比nonatomic性能慢很多。你想嘛,atomic每次访问Set、get方法之前都加一把锁,性能低很多
15、计算执行一段代码所消耗的时间
第一种:
NSDate *begin = [NSDate date]; NSData *data = [NSData dataWithContentsOfURL:url]; NSDate *end = [NSDate date]; NSLog(@"%f",[end timeIntervalSinceDate:begin]);
第二种
CFTimeInterval begin = CFAbsoluteTimeGetCurrent(); NSData *data = [NSData dataWithContentsOfURL:url]; CFTimeInterval end = CFAbsoluteTimeGetCurrent(); NSLog(@"%f",end - begin);
16、分离路径字符串的最后一段元素lastPathComponent
代码示例
NSString *urlPath = @"https://www.jianshu.com/u/8bacdb9ecf00"; NSString *fileName = [urlPath lastPathComponent]; NSLog(@"%@",fileName); //打印结果:8bacdb9ecf00
解释: (来源于苹果官方文档注释)
The last path component of the receiver.
Path components are alphanumeric strings delineated by the path separator (slash “/”) or the beginning or end of the path string. Multiple path separators at the end of the string are stripped.
Note that this method only works with file paths (not, for example, string representations of URLs).
- lastPathComponent 是系统为NSString添加的PathExtensions中的一个方法,目的是获取一段路径字符串的最后一段内容。
路径是一串字母数字、放在字符串的开头或者结尾路径分隔符(/)的组合。放在字符串最后的/大多数情况被省略掉。
注意:这个方法仅仅对字符串类型的路径和链接,对于NSURL类型的需要先转换成NSString对象类型。
举例说明lastPathComponent对多种字符串的剪裁效果
Receiver’s String Value | String Returned |
---|---|
/tmp/scratch.tiff | scratch.tiff |
/tmp/scratch | scratch” |
/tmp/ | tmp |
scratch/// | scratch |
/ | / |
作者:SmallWhiteMouse
链接:https://www.jianshu.com/p/3f66835bb8b1