***********單例**************************************
http://www.kuqin.com/shuoit/20140120/337708.html對單例創(chuàng)建安全有考慮咬荷。普通創(chuàng)建模式://頭文件 提供類方法API#import@interface ZBSingleton : NSObject
+ (instancetype) shareInstance;
@end
//實(shí)現(xiàn)文件
#import "ZBSingleton.h"
@implementation ZBSingleton
//static 修飾全局咳促,聲明一個(gè)唯一內(nèi)存的變量,初始化為nil
static ZBSingleton* _instance = nil;
//類方法返回唯一對象翎猛,而且痣被初始化一次
+(instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init];
});
return _instance;
}
//重寫alloc 方法:不會(huì)被alloc init重新分配新地址捉捅,返回當(dāng)前實(shí)例對象
+(id)allocWithZone:(struct _NSZone *)zone
{
return [ZBSingleton shareInstance];
}
//重寫copy方法,返回當(dāng)前實(shí)例對象
-(id) copyWithZone:(struct _NSZone *)zone
{
return [ZBSingleton shareInstance];
}
******GCD - Operation等*************************
http://www.reibang.com/p/0b0d9b1f1f19
1忆肾、GCD
(1)表格關(guān)系:
同步執(zhí)行 ? ? ? ? 異步執(zhí)行
串行隊(duì)列 當(dāng)前線程白指,一個(gè)一個(gè)執(zhí)行 其他線程较坛,一個(gè)一個(gè)執(zhí)行
并行隊(duì)列 當(dāng)前線程印蔗,一個(gè)一個(gè)執(zhí)行 開很多線程,一起執(zhí)行
(2)關(guān)于隊(duì)列:
》》主隊(duì)列:一個(gè)特殊的 串行隊(duì)列丑勤。什么是主隊(duì)列:用于刷新 UI华嘹,任何需要刷新 UI 的工作都要在主隊(duì)列執(zhí)行,
所以一般耗時(shí)的任務(wù)都要放到別的線程執(zhí)行法竞。
//OBJECTIVE-C
dispatch_queue_t queue = ispatch_get_main_queue();
//SWIFT
let queue = ispatch_get_main_queue()
》》自己創(chuàng)建的隊(duì)列:自己可以創(chuàng)建 串行隊(duì)列, 也可以創(chuàng)建 并行隊(duì)列耙厚。
它有兩個(gè)參數(shù),第一個(gè)上面已經(jīng)說了岔霸,第二個(gè)才是最重要的薛躬。
第二個(gè)參數(shù)用來表示創(chuàng)建的隊(duì)列是串行的還是并行的,
傳入 DISPATCH_QUEUE_SERIAL 或 NULL 表示創(chuàng)建串行隊(duì)列呆细。serial
傳入 DISPATCH_QUEUE_CONCURRENT 表示創(chuàng)建并行隊(duì)列型宝。
concurrent
//OBJECTIVE-C
//串行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL);
//并行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT);
//SWIFT
//串行隊(duì)列
let queue = dispatch_queue_create("tk.bourne.testQueue", nil);
let queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL)
//并行隊(duì)列
let queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT)
》》全局并行隊(duì)列:只要是并行任務(wù)一般都加入到這個(gè)隊(duì)列。這是系統(tǒng)提供的一個(gè)并發(fā)隊(duì)列絮爷。
//OBJECTIVE-C
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//SWIFT
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//1.任務(wù)一:下載圖片
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載圖片 - %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
趴酣。。坑夯。
岖寞。。柜蜈。
//4.設(shè)置依賴
[operation2 addDependency:operation1];? ? ? //任務(wù)二依賴任務(wù)一
[operation3 addDependency:operation2];? ? ? //任務(wù)三依賴任務(wù)二
注意:不能添加相互依賴仗谆,會(huì)死鎖,比如 A依賴B淑履,B依賴A胸私。
可以使用 removeDependency 來解除依賴關(guān)系恒削。
//5.創(chuàng)建隊(duì)列并加入任務(wù)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
*******線程沖突問題******************
2.1线召、@synchronized? ['s??kr? na?z d]同步
NSObject *obj = [[NSObject alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(obj) {
NSLog(@"需要線程同步的操作1 開始");
sleep(3);
NSLog(@"需要線程同步的操作1 結(jié)束");
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
@synchronized(obj) {
NSLog(@"需要線程同步的操作2");
}
});
@synchronized(obj)指令使用的obj為該鎖的唯一標(biāo)識军俊,只有當(dāng)標(biāo)識相同時(shí),才為滿足互斥缆娃,
如果線程2中的@synchronized(obj)改為@synchronized(self),剛線程2就不會(huì)被阻塞捷绒,
@synchronized指令實(shí)現(xiàn)鎖的優(yōu)點(diǎn)就是我們不需要在代碼中顯式的創(chuàng)建鎖對象,便可以實(shí)現(xiàn)鎖的機(jī)制贯要,但作為一種預(yù)防措施暖侨,
@synchronized塊會(huì)隱式的添加一個(gè)異常處理例程來保護(hù)代碼,該處理例程會(huì)在異常拋出的時(shí)候自動(dòng)的釋放互斥鎖崇渗。
所以如果不想讓隱式的異常處理例程帶來額外的開銷字逗,你可以考慮使用鎖對象。
上面結(jié)果的執(zhí)行結(jié)果為:
2016-06-29 20:48:35.747 SafeMultiThread[35945:580107] 需要線程同步的操作1 開始
2016-06-29 20:48:38.748 SafeMultiThread[35945:580107] 需要線程同步的操作1 結(jié)束
2016-06-29 20:48:38.749 SafeMultiThread[35945:580118] 需要線程同步的操作2
2.2宅广、dispatch_semaphore
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(signal, overTime);
NSLog(@"需要線程同步的操作1 開始");
sleep(2);
NSLog(@"需要線程同步的操作1 結(jié)束");
dispatch_semaphore_signal(signal);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(signal, overTime);
NSLog(@"需要線程同步的操作2");
dispatch_semaphore_signal(signal);
});
dispatch_semaphore是GCD用來同步的一種方式葫掉,與他相關(guān)的共有三個(gè)函數(shù),
分別是dispatch_semaphore_create跟狱,dispatch_semaphore_signal俭厚,dispatch_semaphore_wait。
(1)dispatch_semaphore_create的聲明為:
1
dispatch_semaphore_t dispatch_semaphore_create(long value);
傳入的參數(shù)為long驶臊,輸出一個(gè)dispatch_semaphore_t類型且值為value的信號量挪挤。
值得注意的是,這里的傳入的參數(shù)value必須大于或等于0关翎,否則dispatch_semaphore_create會(huì)返回NULL扛门。
(2)dispatch_semaphore_signal的聲明為:
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
這個(gè)函數(shù)會(huì)使傳入的信號量dsema的值加1;
(3) dispatch_semaphore_wait的聲明為:
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
這個(gè)函數(shù)會(huì)使傳入的信號量dsema的值減1纵寝;這個(gè)函數(shù)的作用是這樣的论寨,如果dsema信號量的值大于0,該函數(shù)所處線程就繼續(xù)執(zhí)行下面的語句店雅,
并且將信號量的值減1政基;如果desema的值為0,那么這個(gè)函數(shù)就阻塞當(dāng)前線程等待timeout(注意timeout的類型為dispatch_time_t闹啦,
不能直接傳入整形或float型數(shù))沮明,如果等待的期間desema的值被dispatch_semaphore_signal函數(shù)加1了,
且該函數(shù)(即dispatch_semaphore_wait)所處線程獲得了信號量窍奋,那么就繼續(xù)向下執(zhí)行并將信號量減1荐健。
如果等待期間沒有獲取到信號量或者信號量的值一直為0,那么等到timeout時(shí)琳袄,其所處線程自動(dòng)執(zhí)行其后語句江场。
dispatch_semaphore 是信號量,但當(dāng)信號總量設(shè)為 1 時(shí)也可以當(dāng)作鎖來窖逗。在沒有等待情況出現(xiàn)時(shí)址否,它的性能比 pthread_mutex 還要高,
但一旦有等待情況出現(xiàn)時(shí)碎紊,性能就會(huì)下降許多佑附。相對于 OSSpinLock 來說樊诺,它的優(yōu)勢在于等待時(shí)不會(huì)消耗 CPU 資源。
如上的代碼音同,如果超時(shí)時(shí)間overTime設(shè)置成>2词爬,可完成同步操作。如果overTime<2的話权均,在線程1還沒有執(zhí)行完成的情況下顿膨,
此時(shí)超時(shí)了,將自動(dòng)執(zhí)行下面的代碼叽赊。
上面代碼的執(zhí)行結(jié)果為:
2016-06-29 20:47:52.324 SafeMultiThread[35945:579032] 需要線程同步的操作1 開始
2016-06-29 20:47:55.325 SafeMultiThread[35945:579032] 需要線程同步的操作1 結(jié)束
2016-06-29 20:47:55.326 SafeMultiThread[35945:579033] 需要線程同步的操作2
如果把超時(shí)時(shí)間設(shè)置為<2s的時(shí)候恋沃,執(zhí)行的結(jié)果就是:
2016-06-30 18:53:24.049 SafeMultiThread[30834:434334] 需要線程同步的操作1 開始
2016-06-30 18:53:25.554 SafeMultiThread[30834:434332] 需要線程同步的操作2
2016-06-30 18:53:26.054 SafeMultiThread[30834:434334] 需要線程同步的操作1 結(jié)束
********************************************************************
@interfaceLTButton :UIButton
//-(void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
-(void)addEvent:(UIControlEvents)event Block:(void(^)(UIButton*))block;
-(void(^)(UILabel*))returnBlock:(void(^)(UIButton*))block;
@end
***************************block*****************************************
#import"LTButton.h"
@interfaceLTButton()
@property(nonatomic,strong)void(^block)(UIButton*);
@property(nonatomic,strong)void(^labblock)(UILabel*);
@end
@implementationLTButton
//-(void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents{
//
//}
-(void)addEvent:(UIControlEvents)event Block:(void(^)(UIButton*))block{
self.block= block;
[selfaddTarget:selfaction:@selector(btnAction:)forControlEvents:event];
}
-(void)btnAction:(UIButton*)btn{
if(self.block) {
self.block(btn);
}
}
-(void(^)(UILabel*))returnBlock:(void(^)(UIButton*))block{
//self.block = block;
block(self);
//if (self.block) {
//self.block(self);
//
//}
//void (^blockstr)(NSString *) = ^(NSString *str1){
//str1 = @"str1";
//
//};
self.labblock= ^(UILabel*lab2){
lab2.text=@"ret lab name!";
};
returnself.labblock;
}
**************************block******************************************
@interfaceBlockVCtrl :UIViewController
@property(nonatomic,copy)void(^ colorBlock) (UIColor*color);
@property(nonatomic,strong)UILabel*lab1;
@end
********************************************************************
- (void)viewDidLoad {
[superviewDidLoad];
LTButton* btn = [[LTButtonalloc]initWithFrame:CGRectMake(0,60,100,100)];
[btnsetBackgroundColor:[UIColorredColor]];
[self.viewaddSubview:btn];
__weaktypeof(self) weakSelf =self;
[btnaddEvent:UIControlEventTouchUpInsideBlock:^(UIButton* blockBtn) {
[blockBtnsetTitle:@"wanghu"forState:UIControlStateNormal];
weakSelf.view.backgroundColor= [UIColorredColor];
}];
LTButton* btn2 = [[LTButtonalloc]initWithFrame:CGRectMake(150,64,100,100)];
[self.viewaddSubview:btn2];
[btn2setBackgroundColor:[UIColorblueColor]];
UILabel* btn3 = [[UILabelalloc]initWithFrame:CGRectMake(150,264,100,100)];
[self.viewaddSubview:btn3];
[btn3setBackgroundColor:[UIColorblueColor]];
void(^retBlock)(UILabel*) = [btn2returnBlock:^(UIButton* btnReturn) {
[btnReturnsetTitle:@"btn Return"forState:UIControlStateNormal];
[btnReturnsetBackgroundColor:[UIColororangeColor]];
}];
retBlock(btn3);
void(^block1)() = ^ {
NSLog(@"return nothing !");
};
block1();
//void無返回類型
void(^block2) (int) = ^(intaa) {
NSLog(@"return int aa == %D",aa);
};
block2(3);//調(diào)用block方法時(shí),才回執(zhí)行block里面的方法.
//返回類型block名稱傳入?yún)?shù)實(shí)現(xiàn)方法傳入的參數(shù)
NSString*(^block3) (NSString*) = ^(NSString*str3) {
str3 =@"hahh";
returnstr3;
};
NSLog(@"%@",block3);
/////////////////////////
intx =5;
int(^block4)(int) = ^(inty) {
intz = x + y;//x值編譯就確定為常量5,而不會(huì)受到外面x變量影響
returnz;
};
NSLog(@"%d,%d",x +=5,block4(5));
//x值先自增5 ,x = 10;然后執(zhí)行block4里面的方法,參數(shù)值5, z = 5 + 5;
__blockintx2 =5;
int(^block5) (int) = ^(inty){
intz = x2 + y;//x2受到外面x2變量影響
returnz;
};
NSLog(@"%d,%d",x2 +=5,block5(5));
//x2值先自增5 ,x2 = 10;然后執(zhí)行block5里面的方法,參數(shù)值5, z = 10 + 5;
self.view.backgroundColor= [UIColorwhiteColor];
__weaktypeof(self.lab1) weakLab =self.lab1;
self.colorBlock= ^(UIColor* color){
__strongtypeof(weakLab) storLab = weakLab;
storLab.text=@"ahhahah";
};
/*
Block為什么用copy(或者strong也行)修飾?
默認(rèn)情況下,block是存檔在棧中蛇尚,可能被隨時(shí)回收芽唇,通過copy操作可以使其在堆中保留一份,相當(dāng)于一直強(qiáng)引用著,因此如果block中用到self時(shí),需要將其弱化,通過__weak或者_(dá)_unsafe_unretained.以下是示例代碼及其說明,讀者可以試著打印出不同情況下block的內(nèi)存情況
在調(diào)用時(shí)需要把Block先賦值給本地變量,以防止Block突然改變取劫。因?yàn)槿绻贿@樣的話匆笤,即便是先判斷了Block屬性不為空,在調(diào)用之前谱邪,一旦另一個(gè)線程把Block屬性設(shè)空了炮捧,程序就會(huì)crash,如下代碼:
if (self.myBlock)
{
//此時(shí)惦银,走到這里咆课,self.myBlock可能被另一個(gè)線程改為空,造成crash
//注意:atomic只會(huì)確保myBlock的原子性扯俱,這種操作本身還是非線程安全的
self.myBlock(123);
}
所以正確的代碼是(ARC):
MyBlockType block = self.myBlock;
//block現(xiàn)在是本地不可變的
if (block)
{
block(123);
}
*/
}
-(void)onTapBtn:(UIButton*)btn{
}
******************************************************************************
#import"ViewController.h"
#import"LTPerson.h"
#import"LTDog.h"
#import"BlocksKit.h"
#import"BlocksKit+UIKit.h"
#import
#import
@interfaceViewController ()
@property(nonatomic,weak)IBOutletUILabel *label1;
@property(nonatomic,weak)IBOutletUILabel *label2;
@property(nonatomic,weak)IBOutletNSLayoutConstraint *label1Con;
@property(nonatomic,strong) NSTimer* timer;
@property(nonatomic,strong)NSThread *threadloop;
@property(nonatomic,strong) UIImageView *gcdGroupImageV;
@property(nonatomic,strong) UIImageView *imageViewPerform;
//動(dòng)畫
@property(nonatomic,strong) UIImageView *imageViewAnimation;
@property(nonatomic,assign)doubleangle;
@property(nonatomic,strong)UITableView* tableView;
@end
NSString* textC(NSString* ,NSString*);
NSString* textC(NSString* str1,NSString* str2){
return[NSStringstringWithFormat:@"%@%@",str1,str2];
}
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selftestAnimation];
}
#pragma mark -常用動(dòng)畫
- (void)testAnimation {
self.imageViewAnimation = [[UIImageView alloc]initWithFrame:CGRectMake(100,100,100,100)];
self.imageViewAnimation.image = [UIImage imageNamed:@"ANIMALL"];
[self.view addSubview:self.imageViewAnimation];
self.imageViewAnimation.alpha =1.0;
//設(shè)置圓角考慮性能參考:https://github.com/panghaijiao/HJCornerRadius
self.imageViewAnimation.layer.cornerRadius =10.0;
//動(dòng)畫參考:http://zhangmingwei.iteye.com/blog/2101782
//1圖像左右抖動(dòng)
[selftestshakeAnimation];
//2中心旋轉(zhuǎn)動(dòng)畫兩種方法
self.angle =0;
[selftestTransform];
[selftestTransform2];
// 3.某一點(diǎn)旋轉(zhuǎn)
[selftestTransform3];
// 4.關(guān)鍵幀動(dòng)畫(指定路徑動(dòng)畫)
[selftestTransform4];
// 5.翻轉(zhuǎn)動(dòng)畫
//self animationEaseIn:
}
#pragma mark -圖像左右抖動(dòng)
- (void)testshakeAnimation {
CAKeyframeAnimation *shakeAnim = [CAKeyframeAnimation animation];
shakeAnim.keyPath =@"transform.translation.x";
shakeAnim.duration =0.15;
CGFloat delta =10;
shakeAnim.values =@[@0,@(-delta),@(delta),@0];
shakeAnim.repeatCount =12;
[self.imageViewAnimation.layer addAnimation:shakeAnim forKey:nil];
}
#pragma mark -旋轉(zhuǎn)動(dòng)畫-設(shè)置旋轉(zhuǎn)角度
- (void)testTransform {
CGAffineTransform endAngle = CGAffineTransformMakeRotation(self.angle * (M_PI /180.0));
[UIView animateWithDuration:0.5delay:0.1options:UIViewAnimationOptionCurveLinear animations:^{
//UIViewAnimationOptionCurveLinear :動(dòng)畫勻速執(zhí)行书蚪,默認(rèn)值
self.imageViewAnimation.transform = endAngle;
} completion:^(BOOLfinished) {
if(self.angle >720) {
self.angle =self.angle -360.0;
}
self.angle +=10;
[selftestTransform];
}];
}
#pragma mark -旋轉(zhuǎn)動(dòng)畫2 -以z軸為中心,重復(fù)旋轉(zhuǎn)
- (void)testTransform2 {
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI *2.0];
rotationAnimation.duration =0.8;//
rotationAnimation.cumulative =YES;
rotationAnimation.repeatCount =1000;
[self.imageViewAnimation.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
#pragma mark -旋轉(zhuǎn)動(dòng)畫3 -以某一點(diǎn)為中心,重復(fù)旋轉(zhuǎn)
- (void)testTransform3 {
CGAffineTransform endAngle = CGAffineTransformMakeRotation(self.angle * (M_PI /180.0));
[UIView animateWithDuration:0.5delay:0.1options:UIViewAnimationOptionCurveLinear animations:^{
//UIViewAnimationOptionCurveLinear :動(dòng)畫勻速執(zhí)行,默認(rèn)值
self.imageViewAnimation.layer.anchorPoint = CGPointMake(1,1);//以右下角為原點(diǎn)轉(zhuǎn)迅栅,(0,0)是左上角轉(zhuǎn)殊校,(0.5,0,5)心中間轉(zhuǎn),其它以此類推
self.imageViewAnimation.transform = endAngle;
} completion:^(BOOLfinished) {
if(self.angle >720) {
self.angle =self.angle -360.0;
}
self.angle +=10;
[selftestTransform3];//重復(fù)旋轉(zhuǎn)
}];
}
#pragma mark -旋轉(zhuǎn)動(dòng)畫4 -關(guān)鍵幀動(dòng)畫(路徑動(dòng)畫)
- (void)testTransform4 {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
CGMutablePathRef aPath = CGPathCreateMutable();
CGPathMoveToPoint(aPath,nil,20,20);
CGPathAddCurveToPoint(aPath,nil,160,30,220,220,240,420);
animation.path = aPath;
animation.autoreverses =YES;
animation.duration =2;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation.rotationMode =@"auto";
[self.imageViewAnimation.layer addAnimation:animation forKey:@"position"];
}
#pragma mark -翻轉(zhuǎn)動(dòng)畫5 -
+ (void)animationEaseIn:(UIView *)view {
CATransition *animation = [CATransition animation];
[animation setDuration:0.35f];
[animation setType:kCATransitionFade];
[animation setFillMode:kCAFillModeForwards];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[view.layer addAnimation:animation forKey:nil];
}
#pragma mark -線程間通信常用方法
- (void)testPerformSelector {
//轉(zhuǎn)到后臺(tái)下載
[selfperformSelectorInBackground:@selector(backgroundDownd) withObject:nil];
}
- (void)backgroundDownd {
NSURL *urlstr=[NSURL URLWithString:@"fdsf"];
NSData *data=[NSData dataWithContentsOfURL:urlstr];//這一行操作會(huì)比較耗時(shí)
UIImage *image=[UIImage imageWithData:data];
//回到主線程中設(shè)置圖片
//第一種方式:調(diào)用settingImage:方法設(shè)置圖片
//[self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];
//第二種方式
//[self performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
//第三種方式:直接給imageview設(shè)置
[self.imageViewPerform performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
}
- (void)settingImage:(UIImage *)image {
self.imageViewPerform.image = image;
}
#pragma mark -對象加鎖
- (void)testQueueConfict {
NSMutableArray *mutArray = [[NSMutableArray alloc]initWithObjects:@"a",@"b",@"c",@"d",nil];
//對對象進(jìn)行加鎖防止其他線程同時(shí)修改
//注意:鎖定1份代碼只用1把鎖读存,用多把鎖是無效的
//或者鎖定一份代碼:@synchronized (self) {}
@synchronized(mutArray) {
[mutArray removeObject:@"b"];
}
}
#pragma mark -調(diào)試函數(shù)耗時(shí)的利器
- (void)testAbsoluteTime {
//調(diào)試函數(shù)耗時(shí)的利器CFAbsoluteTimeGetCurrent
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
// do something
CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
NSLog(@"time cost: %0.3f", end - start);
}
#pragma mark - GCD常用方法
- (void)testGCD {
//串行
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
//并行
dispatch_queue_t concurrent = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
//同步串行(并行效果一樣) (主線程)
dispatch_sync(serialQueue, ^{
for(inti =0; i <10; i ++) {
NSLog(@"同步串行1");
}
});
dispatch_sync(serialQueue, ^{
for(inti =0; i <10; i ++) {
NSLog(@"同步串行2");
}
});
//異步串行(子線程一個(gè))
dispatch_sync(concurrent, ^{
});
//異步并行(子線程可多個(gè))
dispatch_async(concurrent, ^{
});
/////////////////////////////////////////////////////////////////////////////////
//簡單實(shí)例:實(shí)現(xiàn)合并圖片功能
__blockUIImage *image1;
__blockUIImage *image2;
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSURL *url = [NSURL URLWithString:@"https://"];
image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
});
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSURL *url = [NSURL URLWithString:@"https://"];
image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
});
//創(chuàng)建隊(duì)列組
dispatch_group_t group1 = dispatch_group_create();
//創(chuàng)建全局隊(duì)列組
dispatch_group_async(group1, dispatch_get_global_queue(0,0), ^{
NSURL *url = [NSURL URLWithString:@"https://"];
image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
NSURL *url2 = [NSURL URLWithString:@"https://"];
image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url2]];
});
__weaktypeof(self)weakSelf =self;
//組隊(duì)列任務(wù)執(zhí)行完畢通知
dispatch_group_notify(group1, dispatch_get_global_queue(0,0), ^{
//合并圖片
UIGraphicsBeginImageContext(CGSizeMake(100,100));//開啟上下文繪制位置
[image1 drawInRect:CGRectMake(0,0,100,50)];//繪制上半部分
[image2 drawInRect:CGRectMake(0,50,100,50)];//繪制下半部分
image1 =nil;//清空
image2 =nil;
UIImage *imageCombine = UIGraphicsGetImageFromCurrentImageContext();//保存合并圖片到對象
UIGraphicsEndImageContext();//關(guān)閉上下文
__strongtypeof(weakSelf)strongSelf = weakSelf;//內(nèi)部強(qiáng)引用,防止被提前釋放
//主線程執(zhí)行更新
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.gcdGroupImageV.image = imageCombine;
});
});
}
#pragma mark - Masonry簡單使用
- (void)testMasonry19 {
UIView *view1= [[UIView alloc]init];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(200,300));
make.center.equalTo(self.view);
}];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor orangeColor];
[view1 addSubview:view2];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(view1.mas_centerY);
make.left.equalTo(view1.mas_left).with.offset(10);
make.right.equalTo(view1.mas_centerX).with.offset(-10);
make.top.equalTo(view1.mas_top).with.offset(25);
make.bottom.equalTo(view1.mas_bottom).with.offset(-53);
}];
}
#pragma mark - Realm的常見使用方法
- (void)testRealm {
// Do any additional setup after loading the view, typically from a nib.
//存儲(chǔ)對象
LTPerson* person1 = [[LTPerson alloc]init];
person1.name =@"王虎";
person1.card =@"442398723049012-4";
LTDog* dog1 = [[LTDog alloc]init];
dog1.age =@"3";
dog1.name =@"小宏";
LTDog* dog2 = [[LTDog alloc]init];
dog2.age =@"1";
dog2.name =@"小黑";
[person1.dogs addObject:dog1];
[person1.dogs addObject:dog2];
LTPerson* person2 = [[LTPerson alloc]init];
person2.name =@"SB";
person2.card =@"442398723049012-4";
LTDog* dog11 = [[LTDog alloc]init];
dog1.age =@"3";
dog1.name =@"小宏";
LTDog* dog12 = [[LTDog alloc]init];
dog2.age =@"1";
dog2.name =@"小黑";
[person2.dogs addObject:dog11];
[person2.dogs addObject:dog12];
/*
1
@interface LTDog : RLMObject
@property NSString* age;
@property NSString* name;
@end
RLM_ARRAY_TYPE(LTDog)
注意:
(1) @property NSString *name;
設(shè)置屬性不需要nonatomic, atomic, strong, copy, weak等修飾符
(2)要用Realm的宏“RLM_ARRAY_TYPE“來定義“RLMArray”這個(gè)類型
*/
//2存儲(chǔ)對象
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm addObject:person1];
[realm addObject:person1];
[realm commitWriteTransaction];
//3取出對象
NSMutableArray* doglist = [NSMutableArray array];
RLMResults *persons = [LTPerson objectsWhere:@"name = '王虎'"];
for(LTPerson* personinpersons) {
RLMResults * dogs = [person.dogs objectsWhere:@"name = '小黑'"];
[doglist addObject:dogs];
}
//查詢過濾其它字符設(shè)置:http://www.reibang.com/p/52a9f84b158f
RLMResults *sortedDogs = [LTDog objectsWhere:@"color = 'tan' AND name BEGINSWITH 'B'"];
//4獲取保存在內(nèi)存中的realm數(shù)據(jù)庫
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.inMemoryIdentifier =@"MyInMemoryRealm";
RLMRealm *realmMemory = [RLMRealm realmWithConfiguration:config error:nil];
// 5數(shù)據(jù)更新通知->更新UI
/*
realm通知
假設(shè)這樣的一個(gè)場景为流,當(dāng)數(shù)據(jù)改變時(shí)我們需要更新UI,那怎樣才知道有數(shù)據(jù)改動(dòng)了呢让簿?而且更新UI的操作又需要在主線線程中敬察,而一般DB操作我們會(huì)單獨(dú)啟一個(gè)IO線程,那該如何是好呢尔当?
別急莲祸,Realm為每個(gè)數(shù)據(jù)庫realm對象都設(shè)置了一個(gè)數(shù)據(jù)改變時(shí)的通知:
文/CZ_iOS(簡書作者)
原文鏈接:http://www.reibang.com/p/52a9f84b158f
著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),并標(biāo)注“簡書作者”虫给。
*/
// 5.1 realm整個(gè)數(shù)據(jù)通知
RLMNotificationToken *token = [[RLMNotificationToken alloc]init];
token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
RLMRealm * realmGet = realm;//獲取到通知返回的數(shù)據(jù)
//do something
[selfupdateUI:realmGet];//把返回的數(shù)據(jù)用于更新界面
}];
//如果不需要監(jiān)聽了
[token stop];
// 5.2數(shù)據(jù)對象進(jìn)行監(jiān)控[這里雖然說是數(shù)據(jù)對象藤抡,實(shí)際是是Realm提供的容器類型,比如:RLMResult抹估、RLMArray、RLMLinkingObjectes]
RLMArray *rlmarr = [RLMArray init];
token = [rlmarr addNotificationBlock:^(RLMArray *_Nullablearray, RLMCollectionChange *_Nullablechanges, NSError *_Nullableerror) {
}];
// 6版本兼容問題舊->新
/*
新版本修改模型屬性并新增屬性的情況:線上用戶本地?cái)?shù)據(jù)如何兼容加載?
1之前:
@property NSString *name;
2之后:
@property NSString *firstName;
@property NSString *lastName;
3解決原理:
將老數(shù)據(jù)的name轉(zhuǎn)換成"firstName"弄兜,而lastName則置為"None"药蜻。
然后在用這個(gè)RLMRealmConfiguration創(chuàng)建realm就可以了。
*/
RLMRealmConfiguration *config2 = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion =1;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
if(oldSchemaVersion <1) {
[migration enumerateObjects:LTPerson.className
block:^(RLMObject *oldObject, RLMObject *newObject) {
newObject[@"firstName"] = oldObject[@"name"];
newObject[@"lastName"] =@"Node";
}];
}
};
[RLMRealmConfiguration setDefaultConfiguration:config2];
// 7數(shù)據(jù)加密
/*1 Realm提供了AES-256加密算法并用SHA2進(jìn)行密文校驗(yàn)替饿,使用起來也非常簡單语泽,只要生成一個(gè)256bit的秘鑰(當(dāng)然你要保護(hù)好這個(gè)秘鑰,比如從安全的服務(wù)器信道傳下來)视卢,然后將其給到RLMRealmConfiguration踱卵,在用這個(gè)RLMRealmConfiguration創(chuàng)建realm就可以了
2添加Security.framework框架
3用了Security.framework里面的SecRandomCopyBytes得到一串隨機(jī)數(shù),作為秘鑰据过,然后用這個(gè)秘鑰給到RLMRealmConfiguration創(chuàng)建realm在行使用惋砂,這樣數(shù)據(jù)存儲(chǔ)時(shí)就會(huì)被加密了。
*/
uint8_tbuffer[64];
intrandInt =SecRandomCopyBytes(kSecRandomDefault,64, buffer);
NSData*keyData = [[NSDataalloc]initWithBytes:bufferlength:sizeof(buffer)];
NSLog(@"SecRandomCopyBytes = %d",randInt);
RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
configuration.encryptionKey= keyData;
RLMRealm *realm3 = [RLMRealm realmWithConfiguration:configuration error:nil];
}
//更新界面
- (void)updateUI:(RLMRealm *)realm {
}
#pragma mark - tableview delegete
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
return1;
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
return30;
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell* cell = [tableViewdequeueReusableCellWithIdentifier:@"cell"];
if(cell ==nil) {
cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"cell"];
}
cell.textLabel.text=@"test";
returncell;
}
@end
******************************runtime***********************************************
#import"UILabel+runtimeLab.h"
#import
@implementationUILabel (runtimeLab)
#pragma mark-參考地址:http://www.reibang.com/p/07b6c4a40a90
#pragma mark -添加公共屬性->關(guān)聯(lián)對象
-(void)setName:(NSString*)name {
//這里使用方法的指針地址作為唯一的key
objc_setAssociatedObject(self,@selector(name), name,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString*)name {
returnobjc_getAssociatedObject(self,@selector(name));
}
#pragma mark - Method Swizzling方法交換
/*
自己使用過例子:
使用場景,在iOS7中如果viewdidappear還沒有完成绳锅,就立刻執(zhí)行push或者pop操作會(huì)crash西饵,見我之前寫過的一篇文章iOS7中的pop導(dǎo)致的crash
解決方案就是利用method swizzing,將系統(tǒng)的viewdidappear替換為自己重寫的sofaViewDidAppear
*/
+(void)load {// load系統(tǒng)運(yùn)行該類加載初始化時(shí)就會(huì)調(diào)用
staticdispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
Class selfClass =object_getClass([selfclass]);
SELoriSEL =@selector(setTextColor:);
MethodoriMoth =class_getInstanceMethod(selfClass, oriSEL);
SELcurSEL =@selector(mysetTextColor:);
MethodcurMoth =class_getInstanceMethod(selfClass, curSEL);
BOOLaddSucc =class_addMethod(selfClass, oriSEL,method_getImplementation(curMoth),method_getTypeEncoding(curMoth));
if(addSucc) {
class_replaceMethod(selfClass, curSEL,method_getImplementation(oriMoth),method_getTypeEncoding(oriMoth));
}else{
method_exchangeImplementations(oriMoth, curMoth);
}
});
}
//該類第一次被調(diào)用時(shí)調(diào)用該方法
+(void)initialize {
}
#pragmamark - json->model
- (instancetype)initWithDict:(NSDictionary*)dict {
if(self= [selfinit]) {
//(1)獲取類的屬性及屬性對應(yīng)的類型
NSMutableArray* keys = [NSMutableArrayarray];
NSMutableArray* attributes = [NSMutableArrayarray];
/*
*例子
* name = value3 attribute = T@"NSString",C,N,V_value3
* name = value4 attribute = T^i,N,V_value4
*/
unsignedintoutCount;
objc_property_t* properties =class_copyPropertyList([selfclass], &outCount);
for(inti =0; i < outCount; i ++) {
objc_property_tproperty = properties[i];
//通過property_getName函數(shù)獲得屬性的名字
NSString* propertyName = [NSStringstringWithCString:property_getName(property)encoding:NSUTF8StringEncoding];
[keysaddObject:propertyName];
//通過property_getAttributes函數(shù)可以獲得屬性的名字和@encode編碼
NSString* propertyAttribute = [NSStringstringWithCString:property_getAttributes(property)encoding:NSUTF8StringEncoding];
[attributesaddObject:propertyAttribute];
}
//立即釋放properties指向的內(nèi)存
free(properties);
//(2)根據(jù)類型給屬性賦值setValue
for(NSString* keyinkeys) {
if([dictvalueForKey:key] ==nil)continue;
[selfsetValue:[dictvalueForKey:key]forKey:key];
}
}
returnself;
}
#pragma mark -一鍵序列化實(shí)現(xiàn)NSCoding自動(dòng)歸檔和解檔
/*
原理描述:用runtime提供的函數(shù)遍歷Model自身所有屬性,并對屬性進(jìn)行encode和decode操作鳞芙。
核心方法:在Model的基類中重寫方法:
獲得屬性:Ivar * ivars = class_copyIvarList([self class], &outCount);
NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)];
*/
- (id)initWithCoder:(NSCoder*)aDecoder {
if(self= [superinit]) {
unsignedintoutCount;
Ivar* ivars =class_copyIvarList([selfclass], &outCount);
for(inti =0; i < outCount; i ++) {
Ivarivar = ivars[i];
NSString* key = [NSStringstringWithUTF8String:ivar_getName(ivar)];
[selfsetValue:[aDecoderdecodeObjectForKey:key]forKey:key];
}
}
returnself;
}
- (void)encodeWithCoder:(NSCoder*)aCoder {
unsignedintoutCount;
Ivar* ivars =class_copyIvarList([selfclass], &outCount);
for(inti =0; i < outCount; i ++) {
Ivarivar = ivars[i];
NSString* key = [NSStringstringWithUTF8String:ivar_getName(ivar)];
[aCoderencodeObject:[selfvalueForKey:key]forKey:key];
}
}
@end
***********************************RAC**************************************************
1
//textFild的文字更改監(jiān)聽
[[self.textFild rac_textSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
2
//點(diǎn)擊事件:監(jiān)聽了textFild的UIControlEventEditingChanged事件,button點(diǎn)擊事件也是
[[self.textFild rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(id x){
NSLog(@"改變了");
}];
3
//給我們的某個(gè)label添加一個(gè)手勢動(dòng)作眷柔,我們也可以用簡單的RAC代碼完成
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
[[tap rac_gestureSignal] subscribeNext:^(id x) {
NSLog(@"tap");
}];
[self.view addGestureRecognizer:tap];
4
//代理: AlertView代理也有簡化的代碼。
[[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
5
//通知:發(fā)送名為postdata的通知并傳送一個(gè)數(shù)組dataArray原朝。
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
//而在接受的頁面我們需要增加觀察者并接受數(shù)組驯嘱,這時(shí)我們的RAC就派上用場了。
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
NSLog(@"%@", notification.name);
NSLog(@"%@", notification.object);
}];
6
//RAC中得KVO大部分都是宏定義喳坠,所以代碼異常簡潔鞠评,簡單來說就是RACObserve(TARGET, KEYPATH)這種形式,TARGET是監(jiān)聽目標(biāo)丙笋,KEYPATH是要觀察的屬性值谢澈,這里舉一個(gè)很簡單的例子,如果UIScrollView滾動(dòng)則輸出success御板。
UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
scrolView.contentSize = CGSizeMake(200, 800);
scrolView.backgroundColor = [UIColor greenColor];
[self.view addSubview:scrolView];
[RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
NSLog(@"success");
}];
****************************************函數(shù)式編程***********************************************
.h文件
@interface SQLTool : NSObject
//這里不需要了锥忿,放到.m中去
//@property (nonatomic, strong, readonly) NSString *sql;
//添加這個(gè)方法,參數(shù)是一個(gè)block怠肋,傳遞一個(gè)SQLTool的實(shí)例
+ (NSString *)makeSQL:(void(^)(SQLTool *tool))block;
//定義select的block
typedef SQLTool *(^Select)(NSArray *columns);
@property (nonatomic, strong, readonly) Select select;
...
@end
.m文件
@interface SQLTool ()
//用于保存拼接后的SQL
@property (nonatomic, strong) NSString *sql;
@end
@implementation SQLTool
+ (NSString *)makeSQL:(void(^)(SQLTool *tool))block {
if (block) {
SQLTool *tool = [[SQLTool alloc] init];
block(tool);
return tool.sql;
}
return nil;
}
- (Select)select {
return ^(NSArray *columns) {
if (columns.count > 0) {
self.sql = [NSString stringWithFormat:@"SELECT %@", [columns componentsJoinedByString:@","]];
} else {
self.sql = @"SELECT *";
}
//這里將自己返回出去
return self;
}
}
...
@end
然后調(diào)用時(shí)是這樣的:
NSString *sql = [SQLTool makeSQL:^(SQLTool * tool) {
tool.select(nil).from(@"table").where(@"columnA = 1");
}];
****************************************鏈?zhǔn)骄幊?**********************************************
.h文件
//定義select的block
typedef SQLTool *(^Select)(NSArray *columns);
@property (nonatomic, strong, readonly) Select select;
.m文件
- (Select)select {
return ^(NSArray *columns) {
if (columns.count > 0) {
self.sql = [NSString stringWithFormat:@"SELECT %@", [columns componentsJoinedByString:@","]];
} else {
self.sql = @"SELECT *";
}
//這里將自己返回出去
return self;
}
}
最終實(shí)現(xiàn)的目標(biāo)是以下類似的:
SQLTool *tool = [[SQLTool alloc] init];
NSString*testSQL1 = tool.select(nil).from(@"Table").orderBy(@"Column DESC").sql;
****************SQL常用增刪改查語句********************************************************************
1增
1.1【插入單行】
insert [into] <表名> (列名) values (列值)
例:insert into Strdents (姓名,性別,出生日期) values ('開心朋朋','男','1980/6/15')
1.2【將現(xiàn)有表數(shù)據(jù)添加到一個(gè)已有表】
insert into <已有的新表> (列名) select <原表列名> from <原表名>
例:insert into tongxunlu ('姓名','地址','電子郵件')
select name,address,email
from Strdents
1.3【直接拿現(xiàn)有表數(shù)據(jù)創(chuàng)建一個(gè)新表并填充】
select <新建表列名> into <新建表名> from <源表名>
例:select name,address,email into tongxunlu from strdents
1.4【使用union關(guān)鍵字合并數(shù)據(jù)進(jìn)行插入多行】
insert <表名> <列名> select <列值> tnion select <列值>
例:insert Students (姓名,性別,出生日期)
select '開心朋朋','男','1980/6/15' union(union表示下一行)
select '藍(lán)色小明','男','19**/**/**'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2刪
2.1【刪除<滿足條件的>行】
delete from <表名> [where <刪除條件>]
例:delete from a where name='開心朋朋'(刪除表a中列值為開心朋朋的行)
2.2【刪除整個(gè)表】
truncate table <表名>
truncate table tongxunlu
注意:刪除表的所有行敬鬓,但表的結(jié)構(gòu)、列、約束钉答、索引等不會(huì)被刪除础芍;不能用語有外建約束引用的表
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3改
update <表名> set <列名=更新值> [where <更新條件>]
例:update tongxunlu set 年齡=18 where 姓名='藍(lán)色小名'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4查
4.1``精確(條件)查詢
select <列名> from <表名> [where <查詢條件表達(dá)試>] [order by <排序的列名>[asc或desc]]
4.1.1【查詢所有數(shù)據(jù)行和列】
例:select * from a
說明:查詢a表中所有行和列
4.1.2【查詢部分行列--條件查詢】
例:select i,j,k from a where f=5
說明:查詢表a中f=5的所有行,并顯示i,j,k3列
4.1.3【在查詢中使用AS更改列名】
例:select name as 姓名 from a where xingbie='男'
說明:查詢a表中性別為男的所有行数尿,顯示name列仑性,并將name列改名為(姓名)顯示
4.1.4【查詢空行】
例:select name from a where email is null
說明:查詢表a中email為空的所有行,并顯示name列右蹦;SQL語句中用is null或者is not null來判斷是否為空行
4.1.5【在查詢中使用常量】
例:select name, '唐山' as 地址 from Student
說明:查詢表a诊杆,顯示name列,并添加地址列何陆,其列值都為'唐山'
4.1.6【查詢返回限制行數(shù)(關(guān)鍵字:top percent)】
例1:select top 6 name from a
說明:查詢表a晨汹,顯示列name的前6行,top為關(guān)鍵字
例2:select top 60 percent name from a
說明:查詢表a贷盲,顯示列name的60%淘这,percent為關(guān)鍵字
4.1.7【查詢排序(關(guān)鍵字:order by , asc , desc)】
例:select name
from a
where chengji>=60
order by desc
說明:查詢a表中chengji大于等于60的所有行,并按降序顯示name列巩剖;默認(rèn)為ASC升序
4.2``模糊查詢
4.2.1【使用like進(jìn)行模糊查詢】
注意:like運(yùn)算副只用于字符串铝穷,所以僅與char和varchar數(shù)據(jù)類型聯(lián)合使用
例:select * from a where name like '趙%'
說明:查詢顯示表a中,name字段第一個(gè)字為趙的記錄
4.2.2【使用between在某個(gè)范圍內(nèi)進(jìn)行查詢】
例:select * from a where nianling between 18 and 20
說明:查詢顯示表a中nianling在18到20之間的記錄
4.2.3【使用in在列舉值內(nèi)進(jìn)行查詢】
例:select name from a where address in ('北京','上海','唐山')
說明:查詢表a中address值為北京或者上呵蚣埃或者唐山的記錄氧骤,顯示name字段
4.3``.分組查詢
4.3.1【使用group by進(jìn)行分組查詢】
例:select studentID as 學(xué)員編號,AVG(score) as 平均成績 (注釋:這里的score是列名)
from score (注釋:這里的score是表名)
group by studentID
說明:在表score中查詢,按strdentID字段分組吃引,顯示strdentID字段和score字段的平均值筹陵;select語句中只允許被分組的列和為每個(gè)分組返回的一個(gè)值的表達(dá)式,例如用一個(gè)列名作為參數(shù)的聚合函數(shù)
4.3.2【使用having子句進(jìn)行分組篩選】
例:select studentID as 學(xué)員編號,AVG(score) as 平均成績 (注釋:這里的score是列名)
from score (注釋:這里的score是表名)
group by studentID
having count(score)>1
說明:接上面例子镊尺,顯示分組后count(score)>1的行朦佩,由于where只能在沒有分組時(shí)使用,分組后只能使用having來限制條件庐氮。
4.4``.多表聯(lián)接查詢
4.4.1內(nèi)聯(lián)接
4.4.1.1【在where子句中指定聯(lián)接條件】
例:select a.name,b.chengji
from a,b
where a.name=b.name
說明:查詢表a和表b中name字段相等的記錄语稠,并顯示表a中的name字段和表b中的chengji字段
4.4.1.2【在from子句中使用join?on】
例:select a.name,b.chengji
from a inner join b
on (a.name=b.name)
說明:同上
4.4.2外聯(lián)接
4.4.2.1【左外聯(lián)接查詢】
例:select s.name,c.courseID,c.score
from strdents as s
left outer join score as c
on s.scode=c.strdentID
說明:在strdents表和score表中查詢滿足on條件的行,條件為score表的strdentID與strdents表中的sconde相同
4.4.2.2【右外聯(lián)接查詢】
例:select s.name,c.courseID,c.score
from strdents as s
right outer join score as c
on s.scode=c.strdentID
說明:在strdents表和score表中查詢滿足on條件的行弄砍,條件為strdents表中的sconde與score表的strdentID相同