一、点语法介绍

/*
以前封装后,要给属性赋值,必须调用方法
这样做,有两个缺点:
1.代码量多,调用方法要写的东西多。
2.看起来并不像是给属性赋值,也不像取值。 我们用点语法就可以更好的解决! 点语法的语法:
对象.属性;
注意:这里的属性不需要加_ 对象.属性 = 值; 点语法的本质:
其实就是调用getter或者setter方法。 点语法注意事项:
1.在类的方法里面如果用self.age 这个是调用方法,self->_age 是直接调用成员变量。
2.千万记得不要在setter或者getter方法里面用点语法,否则,死循环。
3.用点语法之前必须保证你的setter和getter方法的方法名符合命名的规范。
提示:点语法,也可以称之为 语法糖。
本质可以理解为是编译器的特性。
因为其他面向对象的语言都是用.来访问属性。
*/ #import <Foundation/Foundation.h>
#import "Person.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
// [p setName:@"刘德华"];
p.name = @"张学友"; //这一句就相当于上一句,编译后也是编译成 [p setName:@"张学友"];
// [p setAge:16];
p.age = ; //这一句就相当于上一句
// [p setWeight:100];
p.weight = ; //这一句就相当于上一句
// NSLog(@"名字=%@ 年龄:%d",[p name],[p age]);
NSLog(@"名字=%@ 年龄:%d",p.name,p.age);
}
return ;
}

二、@property和synthesize关键字

/*
@property
作用:帮我们生成setter和getter方法的声明。
语法:
@property 类型 属性名;
注意:属性名不加_
如果只用@property关键字的话,在实现类中,setter和getter方法需要自己实现。 既然有关键字可以生成setter和getter方法的声明,肯定就有关键字可以生成setter和getter方法的实现。
@synthesize:
作用:自动生成getter和setter方法的实现 语法:
@synthesize 特性名(属性名) @synthesize做了多少事:
1.生成getter和setter方法的实现 2.还会生成一个私有的成员变量,成员变量名字就是特性名 3.实现的方法里是给自己生成的那个私有成员变量赋值 4.如果想指定给某个成员变量赋值,就在特性名后面加一个 = 成员变量名;
例:@synthesize name = _name; 5.如果你想过滤,就自己重写 批量生成方法的实现:
语法:
@synthesize 特性名1,特性名2………………特性名n 批量生成方法的声明:
语法:@property 类型 特性名1,特性名2………………特性名n
例:@property NSString *name,*nickName; 注意:批量生成时,类型必须一致
*/
#import <Foundation/Foundation.h>
@interface Person : NSObject{
NSString *_name;
int _age;
} //这样就会给_name封装getter和setter的声明
@property NSString *name;
/*
-(void)setName:(NSString *)name;
-(NSString *)name;
*/
//这样就会给_age封装getter和setter的声明
@property int age;
/*
-(void)setAge:(int)age;
-(int)age;
*/
-(void)sayHi;
@end //
// Person.m
// OC第五天
//
// Created by iOS001 on 15/11/5.
//
// #import "Person.h" @implementation Person //@synthesize name;//自动生成了_name的getter和setter的实现
//
//@synthesize age;//自动了_age的getter和setter的实现 //@synthesize name = _name;//自动生成了_name的getter和setter的实现
//
//@synthesize age = _age;//自动了_age的getter和setter的实现 @synthesize name = _name,age=_age; //批量操作。 -(void)setAge:(int)age{
if (age < || age > ) {
_age = ;
}else{
_age = age;
}
} /*
-(void)setName:(NSString *)name{
_name = name;
} -(NSString *)name{
return _name;
} -(void)setAge:(int)age{
_age = age;
} -(int)age{
return _age;
}
*/
@end

上面的语法是在Xcode 4.4以前的用法,在现在的新版XCode中,可以不这么复杂。

/*
@property增强使用:
用法跟之前的@property用法,完全一样
但是,它除了能生成声明以外,还能声明实现
而且,它还能帮我们生成私有的成员变量!
做的事:1.声明属性的setter和getter方法的声明
2.实现属性的setter和getter方法
3.生成一个以特性名加下划线的私有成员变量 注意:如果类的属性中已经存在同名的带下划线的成员变量,那么不会帮我们在生成了,操作的就是这个带下划线的成员变量。
@property封装对象类型
@property不能封装C语言数组 */ #import <Foundation/Foundation.h>
@interface Person : NSObject{
NSString *_name;
}
@property NSString *name; @end #import "Person.h" @implementation Person @end /*
1.@property帮我们生成的实现,是没有任何逻辑过滤,如果我们要过滤,就重写。 2.如果getter方法和setter方法都有重写的话,那么@property不会帮我们生成私有成员变量了。
如果非要两个都重写的话,就自己定义一个成员变量。
*/ #import <Foundation/Foundation.h>
@interface Person : NSObject{
int _age;
} @property NSString *name; @property int age;
@end #import "Person.h"
@implementation Person
-(void)setAge:(int)age{
if(age< ||age>){
_age = ;
}else{
_age = age;
}
} -(int)age{
return _age;
}
@end #import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool { Person *p = [Person new]; p.name = @"草稚京"; p.age = -; NSLog(@"p.name=%@ p.age=%d",p.name,p.age); }
return ;
}

三、动态类型和静态类型的概念

/*
动态类型:
简单来说就是编译的时候,并不知道具体是什么类型的对象,直到运行的时候才知道是什么类型的对象
所以,运行的时候确定了对象的类型,然后才会去找到对应的类型里看有没有这个方法,如果有这个方法就执行,没有这个方法就报错 静态类型:
就是编译的时候就知道是什么类型了
比如说 int char float double
int nums[10]; 一旦定义就不可能再调用char *数组,或者改成char *数组 动态类型的好处:
1.灵活
2.为了实现多态
*/
//比如说我现在有3个类,Person、Student、Teacher,三个类中都有SayHi方法。Student和Teacher是继承并重写了Person类中的SayHi方法。
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
#import "Teacher.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
/*
Person *p = [Person new]; //动态类型 // [p study];//因为编译阶段,它并不知道你是什么对象,所以不可能让你调用这个方法
[p performSelector:@selector(study)];//因为这是一个运行时才绑定的方法
*/
/*
printf("请输入序号--0--Person 1--Student 2--Teacher\n");
int num;
scanf("%d",&num);
Person *p;
switch (num) {
case 0:
p = [Person new];
break;
case 1:
p = [Student new];
break; case 2:
p = [Teacher new];
break;
default:
p = [Person new];
break;
}
[p sayHi];//现在编译器知道是哪个对象的sayHi吗???只能运行时才知道??
*/
}
return ;
}

四、id类型的使用

/*
动态类型:
在编译的时候并不知道具体是什么类型的对象,在运行的时候知道是什么类型的对象。
NSObject:根类。所有的人直接或者间接的继承自NSObject。 两个检查:
编译期检查:
因为OC是动态类型语言,那么也就是说类型只有在运行的时候才会被确定,所以在编译的时候没法检查真正指向的对象是类型,所以更加没法知道你指向的对象类型是否包含某个方法
检查范围:1.去检查它的指针类型里面是否有这个成员(属性、方法),如果有就让你编译通过,如果没有
2.就去父类的父类找,如果有,就编译通过,如果没有,再继续找
3.直到找到NSObject都还没有的话,就报错。
一句话概括:就是只会去赋值号左边的类型里找。 运行期检查:
就是运行的时候类型就确定了,所以就可以检查真正的那个对象里面包不包含这个成员了。
1.先去真正的对象类型里面找,如果找到就执行,如果没找到就继续往父类找。
2.去父类找,找到就执行,没找到就继续往父类的父类找,找到就执行,没找到继续往上找。
3.直到找到NSObject还没有,那么就程序运行的时候崩掉(闪退)。 我希望有一种类型的指针可以指向我任意的对象,并且,我用中括号的方式来调用方法,又不会经过编译期检查(编译时不会报错),有没有呢? id类型:
其实就是一个万能指针,所以任何对象都可以指向。
非常方便的体现什么叫动态类型。
任意对象都可以指向! 好处:灵活,任意类型都可以指向,哪怕上一步指向Student对象,下一步可以立即再指向NSString 缺点:因为编译器没有检查类型有没有方法,所以如果直接调用可能会报错 id是万能指针,任意类型的对象都能指向. 然后用id类型的变量可以调用方法,但是编译器不一定会报错,只能在运行时如果没有才报错。 id需要注意的地方:
1.用id类型指向的对象,不能用点语法
2.那能不能直接调用方法来赋值呢?可以!能不能用方法取值?也可以!
id的作用:
1.指向任意类型
2.当做参数传递
注意:虽然任意类型的对象都可以传,但是运行时可能会报错
3.当做返回值返回
注意:任意类型都可以接收,那么很可能运行时会出问题
*/ #import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h" int main(int argc, const char * argv[]) {
@autoreleasepool { /*
Person *p = [Student new]; //动态类型,只有运行的时候才直到指向的是Student对象 //[p sayHi];//编译器的时候也是去Person找,只不过正好这时候Person有 [p study]; //此时会报错,因为这时候是编译期检查,像这种中括号调用方法,都是编译期检查
*/ /*
id p = [Student new]; [p study]; //有没有经历运行期检查??肯定有! [p sayHi]; NSLog(@"%@",p); p = @"哈哈哈哈哈哈"; NSLog(@"%@",p); p = [Person new];
*/ id p = [Person new]; [p study];//运行的时候才知道是Person类型,但是Person及其父类都没有study方法,所以运行报错 /*
[p performSelector:@selector(test)]; //编译的时候没法检查 //[p sayHi];//而是先在真正指向的对象——student里面先找,找到了就执行 // NSLog(@"%@",p);
//
// [p study]; //Xcode编译的时候只会根据你的指针类型来检查,而并不会根据你具体指向的对象类型来检查
//
// NSObject *obj = [Student new];
//
// NSLog(@"%@",obj);
//
*/
}
return ;
}

五、动态类型和动态方法的检测以及响应方法的方法

   1、态类型的检测

/*

 动态类型检测:我们自己写代码来检测对象是否属于一个类。

 因为我们之前用id类型是可以调用任意方法的,编译器不会报错,但是运行时报错。

 所以我们就在想,能不能在调用方法之前,我们自己写代码判断一下id类型指向的对象是不是某一个类,如果是我才让你调用。

 动态类型检测的方法:
1)
语法:[对象 isKindOfClass:Class];
注意:这个方法是用来检测一个对象是不是右边这个类的对象,或者是这个类子类的对象,如果是则返回YES,如果不是返回NO
例: [p isKindOfClass:[Person class] ];
解释:判断p这个对象是不是Person类的对象,或者是Person子类的对象,如果是返回YES,如果不是返回NO。
注意:包括子类的子类,子类的子类的子类………………………… 2)
[对象 isMemberOfClass:Class];
判断 对象 是不是某个类的对象,不包括子类。
跟上面的区别只在于,判断的时候不包括子类。
总结:isKindOfClass不能确切的确定是哪一个具体的类的对象(因为还能包括子类)。
isMemberOfClass 可以确切的知道是不是某一个类(因为不包括子类)。 3)
注意,接下来是类方法
[类名 isSubOfClass:Class];
判断某一个类,是否是另外一个类的子类,包括子类的子类,以及自己类。
也就是说一个类如果是右边这个的类的本类,或者子类或者子类的子类都会返回YES,否则返回NO。
*/ #import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
#import "GoodStudent.h" int main(int argc, const char * argv[]) {
@autoreleasepool { /*
id obj = [Person new]; //我们能不能在调用这个方法之前,自己写代码判断一下,obj是不是Student类型,如果是,我就让你调用,不是,就
//[obj study];//编译不报错,运行报错 if([obj isKindOfClass:[Student class]]){//判断obj是不是student类型 //如果是就执行
[obj study]; }else{ NSLog(@"obj不是Student类型");
}
*/ //isKindOfClass的用法
/*
// id obj = [Person new]; // BOOL res = [obj isKindOfClass:[Student class] ];
//
// NSLog(@"%d",res); //0 // BOOL res = [obj isKindOfClass:[Person class] ];
//
// NSLog(@"%d",res); //1 // BOOL res = [obj isKindOfClass:[NSObject class] ];
//
// NSLog(@"%d",res);//1 id obj = [GoodStudent new]; BOOL res = [obj isKindOfClass:[Person class]]; NSLog(@"%d",res);//也是1
*/ //isMemberOfClass的用法
/*
id obj = [GoodStudent new]; BOOL res1 = [obj isKindOfClass:[Person class] ];//这种方法包括子类 BOOL res2 = [obj isMemberOfClass:[Person class] ];//这种方法不包括子类 NSLog(@"res1=%d res2=%d",res1,res2);//1 0
*/ //isSubOfClass的用法(类方法)
/*
// BOOL res = [Student isSubclassOfClass:[Person class]];
//
// NSLog(@"%d",res);//1 // BOOL res = [GoodStudent isSubclassOfClass:[Person class]];
//
// NSLog(@"%d",res);//1 // BOOL res = [Person isSubclassOfClass:[Person class]];
//
// NSLog(@"%d",res);//1 //这一句是问Person是Student子类吗?
BOOL res = [Person isSubclassOfClass:[Student class]]; NSLog(@"%d",res);//0
*/
}
return ;
}

2、动态方法的检测

/*
因为之前用id类型调用方法,可能会出错,所以我们想先判断一下这个类型是不是拥有某个方法。
之前的做法是,判断一下某个对象是不是某个类的。那能不能具体一点,直接判断一下某个对象有没有某个方法呢?
动态方法检测!
1.(重点)
[对象 respondsToSelector:SEL];
例:[obj respondsToSelector:@selector(study)]
这是在判断obj有没有study这个方法,如果有返回YES,如果没有返回NO
注意:如果传入的是类方法,那么会返回0,因为类方法不属于对象
2.类方法(用的少)
[类名 instancesRespondToSelector:SEL];//判断类方法的
判断某个类是否有某个对象方法,如果有则返回YES,否则返回NO
跟上面效果一样,只不过这是一个类方法用类名判断 */ #import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
#import "GoodStudent.h" int main(int argc, const char * argv[]) {
@autoreleasepool { /*
id obj = [Student new]; //[obj study];//是不是要在这之前判断一下obj指向的对象有没有study这个方法,如果有才调用
if( [obj respondsToSelector:@selector(study)] ){
[obj study];
}else{
NSLog(@"没有study方法");
}
*/ //respondsToSelcetor的用法
/*
id p = [Person new];
BOOL res = [p respondsToSelector:@selector(clsPerson)];
NSLog(@"%d",res);//0
*/
// id obj = [Person new];
// BOOL res = [Person instancesRespondToSelector:@selector(sayHi)];//只能判断对象方法
// NSLog(@"%d",res);
}
return ;
}

3、响应方法的方法

/*

 响应方法就叫调用方法。
以前我们用[]
现在我们用响应方法的方法:
[对象 performSelector:SEL];
调用某个方法,是没有参数的时候
例: [obj performSelector:@selector(sayHi)];
[对象 performSelector:SEL withObject:id];
调用某个方法,是有1个参数的情况
例:[obj performSelector:@selector(sayName:) withObject:@"刘德华"];
//最多只有2个参数
[obj performSelector:(SEL) withObject:(id) withObject:(id)
这是有两个参数的情况
例:[obj performSelector:@selector(sayName:andNickName:)
withObject:@"发哥"
withObject:@"花卷"]; */
#import <Foundation/Foundation.h>
#import "Person.h" int main(int argc, const char * argv[]) {
@autoreleasepool { id obj = [Person new]; //这个是没参数的时候
// [obj performSelector:@selector(sayHi)];
// if([obj respondsToSelector:@selector(sayName:)]){
// //这个是有1个参数的时候
// [obj performSelector:@selector(sayName:) withObject:@"刘德华"];
// }else{
// NSLog(@"没有这个方法");
// } if([obj respondsToSelector:@selector(sayName:andNickName:)]){
//这个是有1个参数的时候
[obj performSelector:@selector(sayName:andNickName:)
withObject:@"发哥"
withObject:@"花卷"];
}else{
NSLog(@"没有这个方法");
}
}
return ;
}

六、构造和重写

1、构造
/*
创建一个对象:
[类名 new];
new关键字做了三件事:
1.开辟堆空间(相当于创建对象)
2.初始化对象
3.返回对象(返回堆空间首地址) 其实new关键字它并不能开辟堆空间和初始化对象
而是调用了两个方法,一个是alloc,一个是init
alloc开辟堆空间(创建对象),然后会返回这个对象
会调用这个alloc返回的对象的init方法,就是初始化对象的
init方法又会返回这个对象(堆空间地址)
构造方法是什么?
构造方法其实就是初始化对象的方法,也就是说init就是我们的构造方法
[Person new] 相当于 [ [Person alloc] init ];
*/ #import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new]; //创建了一个person对象并且初始化
//其实上面的语句类似于下面的步骤
// Person *p2 = [Person alloc];//创建对象
// Person *p3 = [p2 init];//初始化对象
//上面两句可以合并到一句
Person *p2 = [[Person alloc] init];
}
return ;
}
2、重写
/*
init方法会帮我们初始化对象为0,对象类型初始化为nil。
因为默认的只会帮我们初始化为0,我想以后创建对象,都是初始化为我指定的值。
那么就需要重写init方法,因为init方法,因为父类是默认初始化为0,我重写就自己重新赋值就好了。
重写init方法必须符合写法规范
方法体要遵从以下规则:
if( self = [super init] ){
//做想初始化的事
}
return self; 因为有些属性是父类里面提供初始化的,所以一定要加[super init],因为初始化的时候可能会未知原因出错,所以需要判断一下。 instancetype是什么?
之前可以用id作为返回值,但是不安全,因为我可以返回任意类型。
比如说:我其实想返回一个Person对象,但是你给我返回一个OC字符串。。。。
那么编译并不会报错,但是运行时可能出现严重的问题!
所以,问题来了:有没有一种东西,可以让我返回类型,并且安全:意思就是你返回的对象一定是我这个类的。
就要用instancetype
instancetype还可以代表返回的是本类或者子类
注意:instancetype只能做方法的返回值,不能做参数,也不能做类型来定义
总结:instancetype主要是用来返回对象的,而且返回的是本类或子类的对象
*/ #import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h" int main(int argc, const char * argv[]) {
@autoreleasepool { /*
Person *p = [Person new]; [p sayHi];//null 0
*/ // Person *p = [Person dedaoPersonInstance];
//
// [p sayHi];
//
// //这里得到的究竟是Person呢还是Student??
// Student *s = [Student dedaoPersonInstance];
//
//Person *p = [[Person alloc] init];//因为init要返回一个对象,所以用instancetype,因为子类也可能要通过int方法返回对象
Student *s = [[Student alloc] init];
[s sayHi]; }
return ;
} //在Person类的实现类中
+(instancetype)dedaoPersonInstance{
Person *p = [self new]; //当然可以,谁调用就是谁,self就代表Person
return p;
// return @"哈哈哈哈";
} /**
* 重写构造方法
* 返回初始化的对象
*/
-(instancetype)init{
if(self = [super init]){
//现在初始化为以下的值了
_name = @"刘大同";
_age = ;
}
return self;
}
//在Student实现类中
#import "Student.h"
@implementation Student
-(instancetype)init{
if(self = [super init]){
_stuNo = ;
}
return self;
}
-(void)sayHi{
NSLog(@"name=%@,age=%d,id=%d",_name,_age,_stuNo);
} @end
3、自定义构造方法
/*
之前重写构造方法,初始化的值都已经固定写死了,不灵活了
如果我们想一个对象初始化的时候按照我给的值来初始化,怎么办?
就要自定义构造方法,自定义的构造方法里面要给参数
步骤:
1.是一个对象方法
2.以initWith开头,后面接XXXXX
3.有参数(几个参数,根据你想初始化几个值确定)
4.有返回值,类型是instancetype 注意:方法体里面也要遵从规范:
if(self = [super init]){
//初始化的语句
}
return self;
*/ #import <Foundation/Foundation.h>
#import "Person.h" int main(int argc, const char * argv[]) {
@autoreleasepool { // Person *p = [[Person alloc] init];
//
// [p sayHi]; //一定要会用,以后也会经常用到
Person *p = [[Person alloc] initWithName:@"孙悟空" andAge:]; [p sayHi]; }
return ;
} #import "Person.h" @implementation Person
-(instancetype)initWithName:(NSString *)name andAge:(int)age{
if(self = [super init]){
_name = name;
_age = age;
}
return self;
} +(instancetype)dedaoPersonInstance{ Person *p = [self new]; //当然可以,谁调用就是谁,self就代表Person
return p;
// return @"哈哈哈哈";
} /**
* 重写构造方法
* 返回初始化的对象
*/
-(instancetype)init{
if(self = [super init]){
//现在初始化为以下的值了
_name = @"刘大同";
_age = ;
}
return self;
}
-(void)sayHi{
NSLog(@"name=%@ age=%d",_name,_age);
}
@end

oc语言学习之基础知识点介绍(五):OC进阶的更多相关文章

  1. oc语言学习之基础知识点介绍(二):类和对象的进一步介绍

    一.类.对象在内存中的存储 /* 内存分区: 栈:局部变量 堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造 ...

  2. oc语言学习之基础知识点介绍(一):OC介绍

      一.第一个OC程序 #import <Foundation/Foundation.h> //导入头文件 int main(int argc, const char * argv[]) ...

  3. oc语言学习之基础知识点介绍(四):方法的重写、多态以及self、super的介绍

    一.方法重写 /* 重写:当子类继承了父类的方法时,如果觉得父类的方法不适合,那么可以对这个方法进行重新实现,那么这个就重写. 注意:也就是说,一定只能发生在父类和子类关系中. 然后是子类重新实现父类 ...

  4. oc语言学习之基础知识点介绍(三):类方法、封装以及继承的介绍

    一.类方法的使用 /* 像我们之前学的方法,必须先实例化这个类的对象才能调用这个方法,类方法不用实例化对象,直接调用这个方法. 之前学的方法调用的语法: [对象名 方法名]; //对象方法 类方法: ...

  5. c语言学习之基础知识点介绍(三):scanf函数

    本节继续介绍c语言的基础知识点. scanf函数:用来接收用户输入的数据. 语法:scanf("格式化控制符",地址列表); 取地址要用到取地址符:&(shift+7) 例 ...

  6. c语言学习之基础知识点介绍(二):格式化控制符和变量的补充

    上节简单介绍了c语言中的一些基础知识点,本节将对之前介绍的不够详细的知识点进行补充. 格式化控制符的消息介绍: %d的其他控制符: 1.%md:m代表这个整数位占用多少位,m是一个整数.实际数字不足的 ...

  7. c语言学习之基础知识点介绍(五):关系运算式和逻辑运算式

    本节主要说关系运算式和逻辑运算式. 一.关系运算式 1.等于(==):判断左边的表达式是否等于右边的表达式 2.大于(>):判断左边的表达式是否大于右边的表达式 3.大于等于(>=):判断 ...

  8. c语言学习之基础知识点介绍(十五):函数的指针

    一.函数的指针的介绍 /* 函数指针: 函数的指针,本质上一个指针 指向函数的指针,就是一个函数指针. 回忆:我们写的源代码编译成二进制的指令集,一串交给CPU执行的指令 先存在内存里面,然后CPU读 ...

  9. c语言学习之基础知识点介绍(十四):指针的进阶

    一.指针的加.减法运算 /* 1.加法运算 1).可以跟整数进行加法运算,得到的还是一个地址 公式: 地址 + 1 = 地址 + 1 * 类型所占的字节数 地址 + n = 地址 + n * 类型所占 ...

随机推荐

  1. ubuntu 13.04下sublime text 3使用中文输入法

    主要思路参考 http://blog.yanwen.org/archives/1955.html libsublime-imfix.so 这个库自己编译和从他这下载的 md5一样.可以不用编译了.直接 ...

  2. Java 多线程同步的五种方法

    一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...

  3. AlertDialog

    1.AlertDialog点击时不自动消失 //在setPositiveButton和setNegativeButton根据自己的逻辑处理,大概代码如下 if(validate){//验证通过自动消失 ...

  4. Java & XML Tool Overview

    As mentioned in the introduction Sun now provides these tools for XML Processing in Java: StAX Reade ...

  5. hql查询技巧

    要擅于利用对象之间映射的集合去查与其关联的对象,而不是直接在dao层重新写查询的方法,其实,hibernate正是对复杂查询的一种解放,既然有现成的东西,何必再去闭门造车,而且造出来的还是个旧车. 查 ...

  6. [css]《CSS知多少》

    http://www.cnblogs.com/wangfupeng1988/p/4325007.html

  7. MYSQL- 存储过程示例

    最近需要用到MYSQL,没耐心从头到尾,慢慢了解了,需要什么直接百度,直接了解,从实战中学习. 看一下MYSQL存储过程的示例: CREATE PROCEDURE plogin ( p_usernam ...

  8. ECSHOP在线手册之布局参考图-首页 index.dwt

        A.logo替换 1,设置方法 后台商店设置里,上传logo就行,注意logo的名称必须是logo.gif 2,代码相关 page_header.lbi 中 <a href=" ...

  9. ASP.NET线程与异步

    什么是线程? 线程简单来说就是一种数据结构,用来管理这个程序的执行状态,其中包括 1.线程核心对象->寄存器的状态 2.线程环境块,是一块用户模式下的内存,包含线程的异常处理链的头部.线程的局部 ...

  10. 【48】认识template元编程

    1.TMP(template metaprogramming),模版元编程有两个效力:第一,它让某些事情更容易:第二,可将工作从运行期转移到编译期.