黑马程序员_OC的特有语法
2014-06-05 13:16
274 查看
----------------------ASP.Net+Unity开发、.Net培训、期待与您交流!----------------------
Person.h
Person.m
main.m
运行结果:
使用点语法修改成员变量就是调用set方法和get方法,点语言调用更直观地体现成员变量的修改。
Student.h
Student.m
main.m
运行结果:
直接使用property不仅可以直接声明方法完成方法实现,也间接地实现了成员变量地内部定义。虽然在Student没有直接定义成员变量,但是property在方法实现中自动声明了带下划线地成员变量。
Student.h
Student.m
main.m
运行结果:
自动生成的成员变量是私有的,不能直接被外部访问只能在类的内部访问。
Good.h
Good.m
main.m
运行结果:
synthesize可以指定成员变量间的赋值,这样可以保护成员变量被非法访问。
Apple类
Plum类
main.m
运行结果:
定义一个id类型指针之后,id类型的指针变量赋值之后,就可以间接地调用接收类的方法。因为id自身带有*号,所以定义id类型变量时不用加*定义。
phone.h
phone.m
main.m
运行结果:
程序运行完成之后,num成员变量的值初始化成了10。这说明init方法覆写了父类中的init方法。覆写初始化方法也可以不用声明init方法,因为继承NSObject类就已经有了init方法。覆写init方法时,要调用父类中的init方法。
Phone.h
Phone.m
main.m
运行结果:
自定义构造方法可以自由选定传入的参数和类型,这样可以方便灵活地对已经实例化的类进行相应地初始化。使用自定义构造方法时也不能忘了使用父类中的init方法。
[b]Phone.h
Phone.m
main.m
运行结果:
class对象打印出的结果是对应的类名。同时class对象也可以调用对应类的对象方法来初始化对象。
Person.h
Person.m
Car.h
Car.m
main.m
运行结果:
因为程序中有两个类,所以load方法都加载了。由于Car类先调用了方法,所以Car先调用了initialize方法。Person在Car之后定义并使用,因此,Person后调用initialize方法。
Decrit.h
Decrit.m
main.m
运行结果:
默认创建对象时,调用对象方法description方法。如果是用class类型打印,就是调用的类description方法。两者调用的都是description方法,但是两者的调用者和调用的方式不同。
Person.h
Person.m
main.m
运行结果:
sel类型的数据存储的是对象方法的对应地址,使用sel可以通过对应的地址调用对象中的方法。每个类中的方法都有对应的sel数据。
Person.h
Person.m
main.m
运行结果:
sel可以直接调用方法,也可以带参数传入方法中使用。sel是方法调用的另一种体现,可以在只知道方法名而不知道调用方式的时候,间接地调用方法。
----------------------ASP.Net+Unity开发、.Net培训、期待与您交流!----------------------
点语法
1.set方法和get方法的调用
OC中的set方法和get方法都是对成员变量的修改和操作。在方法调用上set方法和get方法都使用中括号来调用,如果仅仅是修改成员变量的值可以直接使用OC的点语法的功能来简化set方法和get方法的调用进而简化重复代码书写。Person.h
@interface Person : NSObject { int _age; NSString *_name; } - (void)setAge:(int)age; - (int)age; - (void)setName:(NSString *)name; - (NSString *)name; @end
Person.m
@implementation Person - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } - (void)setName:(NSString *)name; { _name = name; } - (NSString *)name { return _name; } @end
main.m
int main() { Person *p = [Person new]; p.age = 10; NSLog("age = %d",p.age); p.name = @"seed"; NSLog("name = %@",p.name); return 0; }
运行结果:
2014-06-04 22:19:48.374 ff[527:303] age = 10 2014-06-04 22:19:48.377 ff[527:303] name = seed Program ended with exit code: 0
使用点语法修改成员变量就是调用set方法和get方法,点语言调用更直观地体现成员变量的修改。
2.property声明简化
property的作用就是可以自动声明操作成员变量的set方法和get方法。property同时也自动生成方法的实现,使得set方法和get方法的书写量大为减少。Student.h
@interface Student : NSObject @property int age; @property int score; @end
Student.m
@implementation Student @end
main.m
int main() { Student *s = [Student new]; s.age = 10; NSLog(@"age = %d",s.age); s.score = 100; NSLog(@"score = %d",s.score); return 0; }
运行结果:
2014-06-04 22:31:31.281 ff[560:303] age = 10 2014-06-04 22:31:31.283 ff[560:303] score = 100 Program ended with exit code: 0
直接使用property不仅可以直接声明方法完成方法实现,也间接地实现了成员变量地内部定义。虽然在Student没有直接定义成员变量,但是property在方法实现中自动声明了带下划线地成员变量。
Student.h
@interface Student : NSObject @property int age; @property int score; - (void)test; @end
Student.m
@implementation Student - (void)test { _age = 20; _score = 90; } @end
main.m
int main() { Student *s = [Student new]; s.age = 10; NSLog(@"age = %d",s.age); s.score = 100; NSLog(@"score = %d",s.score); [s test]; NSLog(@"age = %d",s.age); NSLog(@"score = %d",s.score); return 0; }
运行结果:
2014-06-04 22:36:09.619 ff[571:303] age = 10 2014-06-04 22:36:09.622 ff[571:303] score = 100 2014-06-04 22:36:09.623 ff[571:303] age = 20 2014-06-04 22:36:09.624 ff[571:303] score = 90 Program ended with exit code: 0
自动生成的成员变量是私有的,不能直接被外部访问只能在类的内部访问。
3.synthesize的实现
synthesize与property相对,property自动声明方法,synthesize自动完成方法的对应实现。一般synthesize可以省略不写,也可以写明成员变量的赋值保护成员变量不被非法访问。Good.h
@interface Good : NSObject { int _cou; NSString *_na; } @property int count; @property NSString *name; @end
Good.m
@implementation Good @synthesize count = _cou; @synthesize name = _na; @end
main.m
int main() { Good *g = [Good new]; g.count = 10; NSLog(@"count = %d",g.count); g.name = @"buster"; NSLog(@"name = %@",g.name); return 0; }
运行结果:
2014-06-04 23:10:36.334 cc[658:303] count = 10 2014-06-04 23:10:36.338 cc[658:303] name = buster Program ended with exit code: 0
synthesize可以指定成员变量间的赋值,这样可以保护成员变量被非法访问。
构造方法
1.id类型
id就是OC里面的万能指针,各种类型都能指向。定义一个id类型的变量就是定义了一个指向实例对象的一个指针。这个指针可以代替实例变量调用本身的方法。Apple类
Apple.h #import <Foundation/Foundation.h> @interface Apple : NSObject @property int num; @property int size; - (void)test1; - (int)appleSize; @end Apple.m #import "Apple.h" @implementation Apple - (void)test1 { NSLog(@"apple"); } - (int)appleSize { return _size; } @end
Plum类
Plum.h #import <Foundation/Foundation.h> @interface Plum : NSObject @property int num; @property int size; - (void)test2; - (int)plumSize; @end Plum.m #import "Plum.h" @implementation Plum - (void)test2 { NSLog(@"plum"); } - (int)plumSize { return _size; } @end
main.m
#import <Foundation/Foundation.h> #import "Apple.h" #import "Plum.h" int main() { Apple *a = [Apple new]; a.num = 5; NSLog(@"num = %d",a.num); Plum *p = [Plum new]; p.num = 8; NSLog(@"num = %d",p.num); id data = a; [data test1]; int size = [data appleSize]; NSLog(@"size = %d",[data appleSize]); data = p; [data test2]; size = [data plumSize]; NSLog(@"size = %d",size); return 0; }
运行结果:
2014-06-04 23:59:10.820 fru[749:303] num = 5 2014-06-04 23:59:10.823 fru[749:303] num = 8 2014-06-04 23:59:10.825 fru[749:303] apple 2014-06-04 23:59:10.826 fru[749:303] size = 0 2014-06-04 23:59:10.827 fru[749:303] plum 2014-06-04 23:59:10.827 fru[749]
定义一个id类型指针之后,id类型的指针变量赋值之后,就可以间接地调用接收类的方法。因为id自身带有*号,所以定义id类型变量时不用加*定义。
2.init方法
init方法是OC里面对实例化对象进行初始化的方法,这个方法来自于所有类的源头NSObject类。init方法可以直接使用,也可以在子类中覆写,自定义成自己需要的方法。phone.h
@interface Phone : NSObject { int color; int num; } - (void)print; @end
phone.m
@implementation Phone - (id)init { if(self = [super init]) { num = 10; } return self; } - (void)print { NSLog(@"num = %d",num); }
main.m
int main(int argc, const char * argv[]) { Phone *p = [[Phone alloc] init]; [p print]; return 0; }
运行结果:
2014-06-05 10:21:55.987 vv[511:303] num = 10 Program ended with exit code: 0
程序运行完成之后,num成员变量的值初始化成了10。这说明init方法覆写了父类中的init方法。覆写初始化方法也可以不用声明init方法,因为继承NSObject类就已经有了init方法。覆写init方法时,要调用父类中的init方法。
3.自定义构造方法
init方法也可以自己设计定义成自定义构造方法。自定义 构造方法可以自带参数,写成带参数组成的方法。Phone.h
@interface Phone : NSObject @property int color; @property int num; @property NSString *name; - (id)initWithName:(NSString *)name; - (id)initWithNum:(int)num; - (id)initWithName:(NSString *)name andinitWithNum:(int)num; @end
Phone.m
@implementation Phone - (id)initWithName:(NSString *)name { if(self = [super init]) { _name = name; } return self; } - (id)initWithNum:(int)num { if(self = [super init]) { _num = num; } return self; } - (id)initWithName:(NSString *)name andinitWithNum:(int)num { if(self = [super init]) { _num = num; _name = name; } return self; } @end
main.m
#import <Foundation/Foundation.h> #import "Phone.h" int main(int argc, const char * argv[]) { Phone *p = [[Phone alloc] initWithName:@"lsmseed"]; Phone *p1 = [[Phone alloc] initWithNum:10]; Phone *p2 = [[Phone alloc] initWithName:@"seed" andinitWithNum: 20]; NSLog(@"num = %d name = %@",p.num,p.name); NSLog(@"num = %d name = %@",p1.num,p1.name); NSLog(@"num = %d name = %@",p2.num,p2.name); return 0; }
运行结果:
2014-06-05 10:43:08.215 vv[575:303] num = 0 name = lsmseed 2014-06-05 10:43:08.218 vv[575:303] num = 10 name = (null) 2014-06-05 10:43:08.220 vv[575:303] num = 20 name = seed Program ended with exit code: 0
自定义构造方法可以自由选定传入的参数和类型,这样可以方便灵活地对已经实例化的类进行相应地初始化。使用自定义构造方法时也不能忘了使用父类中的init方法。
Class类对象
1.class的使用
class就是类类型,说起来奇怪它也是一种类型,就是类本身也是一种类型。OC中我们写的类也可以当作对象来看,即类对象。实例化后的对象可以调用class方法来获取对应的类对象。[b]Phone.h
@interface Phone : NSObject @property NSString *name; - (id)initWithName:(NSString *)name; @end
Phone.m
@implementation Phone - (id)initWithName:(NSString *)name { if(self = [super init]) { _name = name; } return self; } @end
main.m
int main(int argc, const char * argv[]) { Phone *p = [[Phone alloc] init]; Class pc = [p class]; Phone *p1 = [[pc alloc] initWithName:@"seed"]; NSLog(@"object = %@",pc); NSLog(@"pcname = %@",p1.name); return 0; }
运行结果:
2014-06-05 11:07:14.324 vv[665:303] object = Phone 2014-06-05 11:07:14.328 vv[665:303] pcname = seed Program ended with exit code: 0
class对象打印出的结果是对应的类名。同时class对象也可以调用对应类的对象方法来初始化对象。
2.load方法和initialize方法
load方法就是加载要使用的类,而且类的load方法只调用一次。initialize方法是在类第一次调用时加载,因此initialize方法可以测试出类第一次调用的位置。Person.h
@interface Person : NSObject @property int num; @property NSString *name; @end
Person.m
@implementation Person + (void)load { NSLog(@"Person is loading"); } + (void)initialize { NSLog(@"Person initialize"); } @end
Car.h
@interface Car : NSObject @property int num; @property int color; @end
Car.m
@implementation Car + (void)load { NSLog(@"Car is loading"); } + (void)initialize { NSLog(@"Car initialize"); } @end
main.m
int main(int argc, const char * argv[]) { Car *c = [[Car alloc] init]; NSLog(@"num = %d",c.num); Person *p = [[Person alloc] init]; p.name = @"lsm"; return 0; }
运行结果:
2014-06-05 11:19:34.793 ccc[730:303] Car is loading 2014-06-05 11:19:34.799 ccc[730:303] Person is loading 2014-06-05 11:19:34.808 ccc[730:303] Car initialize 2014-06-05 11:19:34.809 ccc[730:303] num = 0 2014-06-05 11:19:34.809 ccc[730:303] Person initialize Program ended with exit code: 0
因为程序中有两个类,所以load方法都加载了。由于Car类先调用了方法,所以Car先调用了initialize方法。Person在Car之后定义并使用,因此,Person后调用initialize方法。
3.decription方法
decription方法就是对类内容的一个显示,默认情况用NSLog用%@显示的是类名+对象地址。decription的返回值就是NSLog在屏幕上输出的内容。Decrit.h
@interface Decrit : NSObject @property int age; @property NSString *name; @end
Decrit.m
@implementation Decrit - (NSString *)description { return [NSString stringWithFormat:@"seed age is %d",_age]; } + (NSString *)description { return @"seed"; } @end
main.m
int main(int argc, const char * argv[]) { Decrit *d = [[Decrit alloc] init]; NSLog(@"d = %@",d); Class dd = [Decrit class]; NSLog(@"class dd is %@",dd); return 0; }
运行结果:
2014-06-05 12:09:30.759 dd[896:303] d = seed age is 0 2014-06-05 12:09:30.763 dd[896:303] class dd is seed Program ended with exit code: 0
默认创建对象时,调用对象方法description方法。如果是用class类型打印,就是调用的类description方法。两者调用的都是description方法,但是两者的调用者和调用的方式不同。
SEL方法
1.sel的封装定义
sel是OC的一种数据类型的封装。对象是通过sel间接地调用方法。sel数据是调用对象方法的一个桥梁。Person.h
@interface Person : NSObject @property int age; @property NSString *name; - (void)test1; @end
Person.m
@implementation Person - (void)test1 { NSLog(@"test is run"); } @end
main.m
int main(int argc, const char * argv[]) { Person *p = [[Person alloc] init]; p.name = @"lsmseed"; p.age = 10; SEL n = NSSelectorFromString(@"name"); SEL s = @selector(test1); NSLog(@"name is %@",[p performSelector:n]); [p performSelector:s]; return 0; }
运行结果:
2014-06-05 12:39:03.677 sse[988:303] name is lsmseed 2014-06-05 12:39:03.680 sse[988:303] test is run Program ended with exit code: 0
sel类型的数据存储的是对象方法的对应地址,使用sel可以通过对应的地址调用对象中的方法。每个类中的方法都有对应的sel数据。
2.sel方法的调用
sel类型的数据被封装好了之后,一般使用performSelector来调用对应的方法。通过sel获得对应方法的地址后,间接调用方法。Person.h
@interface Person : NSObject @property NSString *name; - (void)test2:(NSString *)name; @end
Person.m
@implementation Person - (void)test2:(NSString *)name { NSString *str = NSStringFromSelector(_cmd); NSLog(@"name = %@",name); NSLog(@"selector = %@",str); } @end
main.m
int main(int argc, const char * argv[]) { Person *p = [[Person alloc] init]; [p performSelector:@selector(test2:) withObject:@"seed"]; return 0; }
运行结果:
2014-06-05 13:13:15.167 sse[1032:303] name = seed 2014-06-05 13:13:15.171 sse[1032:303] selector = test2: Program ended with exit code: 0
sel可以直接调用方法,也可以带参数传入方法中使用。sel是方法调用的另一种体现,可以在只知道方法名而不知道调用方式的时候,间接地调用方法。
----------------------ASP.Net+Unity开发、.Net培训、期待与您交流!----------------------
相关文章推荐
- 黑马程序员-IOS-OC基础-OC特有语法
- 黑马程序员--Objective-C——OC特有语法一
- 黑马程序员--Objective-C——OC特有语法二
- 黑马程序员_ios基础总结9_OC特有语法
- 黑马程序员——OC---OC特有语法01
- 黑马程序员--oc:特有语法1
- 黑马程序员——OC基础---OC特有语法
- 黑马程序员_OC特有语法
- 黑马程序员--oc:特有语法2
- 黑马程序员---OC特有语法(一)
- 黑马程序员-8-Objective-C学习笔记(OC特有语法)
- 黑马程序员——Objective-C语言知识点总结之OC特有语法
- 黑马程序员 OC语言 - 4 OC特有语法
- 黑马程序员---iOS-OC特有的语法1
- 黑马程序员——OC语言------OC特有语法:分类、description、类对象、SEL
- 黑马程序员_oc特有语法一:分类Category和类扩展
- 黑马程序员—OC(归纳总结OC特有的语法)
- 黑马程序员-OC语言基础:OC特有语法
- 黑马程序员---OC特有的语法
- 黑马程序员(OC特有语法-block和-Protocol)