iOS筆記-練習(xí)代碼(三)

***********單例**************************************

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相同

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仙畦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子音婶,更是在濱河造成了極大的恐慌慨畸,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衣式,死亡現(xiàn)場離奇詭異寸士,居然都是意外死亡檐什,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門弱卡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乃正,“玉大人,你說我怎么就攤上這事婶博∥途撸” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵凡蜻,是天一觀的道長搭综。 經(jīng)常有香客問我,道長划栓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任条获,我火速辦了婚禮忠荞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帅掘。我一直安慰自己委煤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布修档。 她就那樣靜靜地躺著碧绞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吱窝。 梳的紋絲不亂的頭發(fā)上讥邻,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機(jī)與錄音院峡,去河邊找鬼兴使。 笑死,一個(gè)胖子當(dāng)著我的面吹牛照激,可吹牛的內(nèi)容都是我干的发魄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俩垃,長吁一口氣:“原來是場噩夢啊……” “哼励幼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起口柳,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤苹粟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后啄清,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體六水,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俺孙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掷贾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睛榄。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖想帅,靈堂內(nèi)的尸體忽然破棺而出场靴,到底是詐尸還是另有隱情,我是刑警寧澤港准,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布旨剥,位于F島的核電站,受9級特大地震影響浅缸,放射性物質(zhì)發(fā)生泄漏轨帜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一衩椒、第九天 我趴在偏房一處隱蔽的房頂上張望蚌父。 院中可真熱鬧,春花似錦毛萌、人聲如沸苟弛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膏秫。三九已至,卻和暖如春做盅,著一層夾襖步出監(jiān)牢的瞬間缤削,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工言蛇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僻他,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓腊尚,卻偏偏與公主長得像吨拗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子婿斥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容