给iOS模拟器录屏 1 xcrun simctl io booted recordVideo filename.mov
iTunes 提交没有版本 2018-04-16 11:41:16 提交到iTunes connect 上看不到版本,可能是某些隐私权限你用到了,但是没有在info.plist中说明,比如说蓝牙,这也不会导致测试环境下的崩溃,但生产下就不行了
GCD的线程数目 GCD会维护一个线程池,而线程池中的线程数目是有上限的,具体数字在64位系统上是64,32位系统还没有机会测试
具体的影响,如下代码
1 2 3 4 5 6 7 8 9 10 11 12 - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t quq = dispatch_queue_create("affa", DISPATCH_QUEUE_CONCURRENT); int taskAmount = 64; for (int i = 0; i<taskAmount; i++) { dispatch_async(quq, ^{ sleep(2); NSLog(@"--%@",[NSThread currentThread]); }); } }
直觉上,因为用了dispatch_async,所以应该不会卡主线程,实际上,因为dispatch_async用光了64条线程,其中包含了主线程,所以界面就会卡2秒。
更进一步,如果这里的taskAmount是64的n(n>=1,n为正整数)倍,那么卡顿时间也会变成2*n秒时间。
这种情况下就需要手动的控制并发数量,其实用NSOperationqueue就可以直接的控制,GCD的话没有直接设置的方法,只能用信号量达到类似效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 dispatch_queue_t workConcurrentQueue = dispatch_queue_create("workQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_queue_t serialQueue = dispatch_queue_create("controllQueue",DISPATCH_QUEUE_SERIAL); dispatch_semaphore_t semaphore = dispatch_semaphore_create(4); // create semaphore: value = 3 dispatch_group_t group = dispatch_group_create(); NSLog(@"begin: %@",[NSThread currentThread]); for (int i = 0; i < 10; i++) { __block int index = i; dispatch_group_async(group, serialQueue, ^{ // If value < 0, then wait here. Else value > 0, then pass, and value -1 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_group_async(group, workConcurrentQueue, ^{ sleep(1); NSLog(@"执行第%d次操作,线程:%@",index, [NSThread currentThread]); dispatch_semaphore_signal(semaphore); // Perform value +1 }); }); } dispatch_group_notify(group, workConcurrentQueue, ^{ NSLog(@"okk"); });
泛型实例化 OC中的泛型是所谓的轻量化泛型,暂时还不知道怎么实现泛型实例化,swift中的实现记录在下面
1 2 3 4 5 6 7 func testFunc<T: NSObject>(cls:T) -> T { let obj = T() return obj } testFunc(cls: NSString())
extern static const 关键字 https://www.jianshu.com/p/2fd58ed2cf55 https://www.jianshu.com/p/3fa703e80720
LayoutIfNeeded小理解 这个方法和另一个方法配对的,setNeedLayout和layoutIfNeed,还有一个关联的方法是layoutSubviews,在我们没有任何干预的情况下,一个view的fram或bounds发生变化时,系统会设置一个flag给这个view,当下一个渲染时机到来时系统会重新按新的布局来渲染视图。setNeedLayout就是我们主动为这个视图设置一个flag,告诉系统这个视图再下一个时机到来时要重新渲染,而layoutIfNeed则是告诉系统,如果设置了flag那么不用等待时机到来了,直接渲染吧。而layoutSubviews这个方法是系统调用的,我们不需要主动调用,我们只需要调用layoutIfNeed就可以了,让系统判断是否在当前时机下立即渲染。
cocoapods https://www.jianshu.com/p/89605e02bf18
Dispatch Source 在这个文章 看到.
详解在这里
Dispatch I/O http://www.cocoachina.com/industry/20130821/6842.html
iOS中NSString转换成HEX(十六进制)-NSData转换成int 1 2 3 4 5 6 NSString *str = @"0xff055008"; //先以16为参数告诉strtoul字符串参数表示16进制数字,然后使用0x%X转为数字类型 unsigned long red = strtoul([str UTF8String],0,16); //strtoul如果传入的字符开头是“0x”,那么第三个参数是0,也是会转为十六进制的,这样写也可以: unsigned long red = strtoul([@"0x6587" UTF8String],0,0); NSLog(@"转换完的数字为:%lx",red);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 // 十六进制转换为普通字符串的。 + (NSString *)stringFromHexString:(NSString *)hexString { // char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1); bzero(myBuffer, [hexString length] / 2 + 1); for (int i = 0; i < [hexString length] - 1; i += 2) { unsigned int anInt; NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)]; NSScanner * scanner = [[[NSScanner alloc] initWithString:hexCharStr] autorelease]; [scanner scanHexInt:&anInt]; myBuffer[i / 2] = (char)anInt; } NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4]; NSLog(@"------字符串=======%@",unicodeString); return unicodeString; } //普通字符串转换为十六进制的。 + (NSString *)hexStringFromString:(NSString *)string{ NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding]; Byte *bytes = (Byte *)[myD bytes]; //下面是Byte 转换为16进制。 NSString *hexStr=@""; for(int i=0;i<[myD length];i++) { NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数 if([newHexStr length]==1) hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; else hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; } return hexStr; }
1 2 3 4 5 6 7 //int 转data int i = 1; NSData *data = [NSData dataWithBytes: &i length: sizeof(i)]; //data 转int int i; [data getBytes: &i length: sizeof(i)];
转自这里