以下的知识点都是我平时的积累 不足之处请多指教
1. 由于证书的原因,安装在手机上的iOS Demo app 运行几天后就无法打开。
2. typedef returnType (^name)(arguments);
typedef void (^btnClickedHandler)(UIButton *sender);
3. #define NS_CLASS_AVAILABLE_IOS(_ios)
NS_CLASS_AVAILABLE_IOS(8.0)// 描述此方法系统8.0以上可用
例子
- (void)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message appearanceProcess:(nullable JXTAlertAppearanceProcess)appearanceProcess actionBlock:(nullable JXTAlertActionBlock)actionBlock NS_CLASS_AVAILABLE_IOS(8.0);
4.宏定义:NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END
如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。
苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END。
在这两个宏之间的代码,所有简单指针对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针。
如下代码所示:
NS_ASSUME_NONNULL_BEGIN
@interface TestNullabilityClass ()
@property (nonatomic, copy) NSArray * items;
- (id)itemWithName:(nullable NSString *)name;
@end
NS_ASSUME_NONNULL_END
在上面的代码中:
items属性默认是nonnull的
itemWithName:方法的返回值也是nonnull,而参数是指定为nullable的
不过,为了安全起见,苹果还制定了几条规则:
1.typedef定义的类型的nullability特性通常依赖于上下文,即使是在Audited Regions中,也不能假定它为nonnull。
2.复杂的指针类型(如id *)必须显示去指定是nonnull还是nullable。例如,指定一个指向nullable对象的nonnull指针,可以使用”__nullable id * __nonnull”。
3.我们经常使用的NSError **通常是被假定为一个指向nullable NSError对象的nullable指针。
5.把 "www.zhidao.baidu.com" 这样的字符串改成 "com/baidu/zhidao/www"
NSArray 逆序reverseObjectEnumerator
NSString *string = @"www.zhidao.baidu.com";
NSArray *array = [string componentsSeparatedByString:@"."];
NSArray *resultArray = [[array reverseObjectEnumerator] allObjects];
NSString *resultString = [resultArray componentsJoinedByString:@"/"];
NSLog(@"result:%@", resultString);
NSEnumerator 遍历
NSLog(@"------- 枚举器法---------");
// ObjectEnumerator 正序
// reverseObjectEnumerator 逆序
NSEnumerator *enumerator = [array reverseObjectEnumerator];
id obj = nil; // 不确定数组里面具体对象的类型,所以定义成id 类型指针
while (obj = [enumerator nextObject]) { // 通过枚举器,取数组里面的每一个元素
NSLog(@"%@", obj); // 将元素赋给 obj, 直到数组结束
//取到的结果为nil,退出while
}
打印结果:
6.__func__ 当前函数名
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// __func__ 当前函数名
NSLog(@"%@ == %s", NSStringFromClass([self class]), __func__);
}
打印:
7.页面A to 页面B , 页面A的viewDidDisappear方法和 页面B的viewDidAppear方法哪个先调用?
分两种情况 push 和 present
A和B分别添加如下代码:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"%@ == %s", NSStringFromClass([self class]), __func__);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"%@ == %s", NSStringFromClass([self class]), __func__);
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(@"%@ == %s", NSStringFromClass([self class]), __func__);
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
NSLog(@"%@ == %s", NSStringFromClass([self class]), __func__);
}
A push B:
A present B:
结果并不相同哦~
ApushB,先执行A的viewDidDisappear 后执行B的viewDidAppear;
ApresentB, 先执行B的viewDidAppear后执行A的viewDidDisappear;
8.使用GCD实现需求:A、B、C 三个任务并发,完成后执行任务D
typedef void(^demoBlock)(NSString *str);
- (void)demoBlock:(demoBlock)block {
block(@"finish");
}
1.
// A.
// 创建一个队列
// 参数1:队列名(C语言写法)
// 参数2:队列类型(串行/并行)
// DISPATCH_QUEUE_SERIAL 串行
// DISPATCH_QUEUE_CONCURRENT 并行
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
// 创建一个调度组
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"===A===");
});
dispatch_group_async(group, queue, ^{
NSLog(@"===B===");
});
dispatch_group_async(group, queue, ^{
NSLog(@"===C===");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"===D finfished===");
});
打印
2.
// B.
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[self demoBlock:^(NSString *str) {
NSLog(@"===A===");
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self demoBlock:^(NSString *str) {
NSLog(@"===B===");
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self demoBlock:^(NSString *str) {
NSLog(@"===C===");
dispatch_group_leave(group);
}];
// 获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_group_notify(group, mainQueue, ^{
NSLog(@"===D finished");
});
打印:
3.应用信号量
// C.
// 获取全局队列
// 参数1:选择的是哪个优先级的全局队列
// 参数2:暂时没用,只能填0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, globalQueue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self demoBlock:^(NSString *str) {
NSLog(@"===A===");
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_async(group, globalQueue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self demoBlock:^(NSString *str) {
NSLog(@"===B===");
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_async(group, globalQueue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self demoBlock:^(NSString *str) {
NSLog(@"===C===");
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_notify(group, globalQueue, ^{
NSLog(@"===D finished===");
});
打印: