Xcode下载解决办法:到该地址去手动下载安装器安装:
https://idmsa.apple.com/IDMSWebAuth/signin?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Fdownload%2Fmore%2F&rv=1
打开PDF文件:https://github.com/SaiBeiGuYan/QLPreviewControllerDemo
1.iOS 播放音效
#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(SystemSoundID)getSystemSoundID{
// 加载音效
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle] pathForResource:@"wangzha.mp3" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
return soundID;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 播放音效
AudioServicesPlaySystemSound([self getSystemSoundID]);
}
@end
2.父子控制器
#import "ViewController.h"
#import "SonViewController.h"
@interface ViewController ()
@property(strong, nonatomic) SonViewController *svc;
@property(strong, nonatomic) UIViewController *cvc;
- (IBAction)change:(id)sender;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
//添加两个子控制器
[self addAnotherChild];
[self addOneChild];
}
-(void)addAnotherChild{
self.svc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"abc"];
//添加某个控制器为当前控制器的子控制器
[self addChildViewController:self.svc];
self.svc.view.frame = CGRectMake(10, 100, self.view.frame.size.width - 20, 200);
//一般情况下,只要控制器成为了子控制器,那么view也应该成为子view
[self.view addSubview:self.svc.view];
}
-(void)addOneChild{
UIViewController *vc = [[UIViewController alloc]init];
vc.view.backgroundColor = [UIColor greenColor];
vc.view.frame = CGRectMake(10, 100, self.view.frame.size.width - 20, 200);
[self addChildViewController:vc];
[self.view addSubview:vc.view];
self.cvc = vc;
}
- (IBAction)change:(id)sender {
UISwitch *switc = (UISwitch *)sender;
if ([switc isOn]) {
//同一个控制器的子控制器之间可以用如下的方式添加切换动画 前提是它们两个必须先添加到同一个父控制器
[self transitionFromViewController:self.cvc toViewController:self.svc duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[self.cvc.view removeFromSuperview];
} completion:^(BOOL finished) {
NSLog(@"%@", self.childViewControllers);
}];
}
else{
[self transitionFromViewController:self.svc toViewController:self.cvc duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[self.svc.view removeFromSuperview];
} completion:^(BOOL finished) {
NSLog(@"%@", self.childViewControllers);
}];
}
}
//移除控制器与视图
//-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//
//
// [self.cvc removeFromParentViewController];
//
// NSLog(@"%@", self.cvc.view);
//
// [self.cvc.view removeFromSuperview];
//
//}
//
@end
3.线程之间通讯
// 不能在子线程中更新主界面 ---> 子线程进行耗时操作,回到主线程进行界面更新的 模式 ---> 线程之间通信问题
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *username;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self operationMode];
}
//NSOperation
-(void)operationMode{
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:2.0];
[NSOperationQueue.mainQueue addOperationWithBlock:^{
self.username.text = @"欢迎你,张三";
}];
}];
}
//GCD模式
-(void)gcdMode{
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2.0];
dispatch_async(dispatch_get_main_queue(), ^{
self.username.text = @"欢迎你,张三";
});
});
}
//NSThread模式
-(void)threadMode{
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(updateUI) object:nil];
[thread start];
}
-(void)updateUI{
[NSThread sleepForTimeInterval:2.0];
[self performSelectorOnMainThread:@selector(updateOnMain) withObject:nil waitUntilDone:NO];
}
-(void)updateOnMain{
self.username.text = @"欢迎你,张三";
}
@end
4.多线程互斥锁
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic, assign) int totalTicket;
@property(nonatomic, strong) NSLock *lock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_totalTicket = 20;
_lock = [[NSLock alloc]init];
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(buyTicket) object:nil];
thread1.name = @"窗口1";
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(buyTicket) object:nil];
thread2.name = @"窗口2";
NSThread *thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(buyTicket) object:nil];
thread3.threadPriority = 50.0;
thread3.name = @"窗口3";
[thread1 start];
[thread2 start];
[thread3 start];
}
#pragma mark - 解决方法一@synchronized
-(void)buyTicket{
while (true) {
[NSThread sleepForTimeInterval:1];
//对于临界资源 多线程访问往往会出现问题 加锁可以解决
//加锁的结果:每次只有一个线程可以访问临界资源
//加锁是一个标志,当该资源没有线程访问的时候,🔒标志为0,当第一个线程来的时候,🔒的标志为1,第一个线程开始访问临界资源
//如果此时有其他线程来访问该临界资源,先要看看🔒是不是为0,如果是1,则阻塞自己,等待上一个线程访问结束。
//第一个线程访问结束以后,🔒的标志为0,这时候通知那些准备访问该资源的线程可以来访问了,这时候按照顺序(CPU调度)来继续访问
@synchronized (self) {
if (_totalTicket > 0) {
_totalTicket--;
NSLog(@"%@卖出去一张票,还剩%d", [NSThread currentThread].name, _totalTicket);
}
else{
NSLog(@"卖完了! %@",[NSThread currentThread].name);
break;
}
}
}
}
#pragma mark - 解决方法一NSLock
-(void)buyTicket2{
while (true) {
[NSThread sleepForTimeInterval:1];
//加锁
[_lock lock];
if (_totalTicket > 0) {
_totalTicket--;
NSLog(@"%@----%d", [NSThread currentThread].name,_totalTicket);
}
else{
NSLog(@"卖完了! %@",[NSThread currentThread].name);
break;
}
//解锁
[_lock unlock];
}
}
@end