------- android培训、iOS培训、Java培训、.NET培训期待与您交流! ----------
PS:重点掌握核心语法!
说明:
1、OC面向对象开发技巧
2、核心语法
(一)、OC--面向对象--开发技巧
1、NSString使用:
1> OC中输出字符串:%@;
2> 创建OC字符串方式:
① NSString *str = @”itcast”;//最简单
② NSString *newStr =[NSString stringWithFormat:@”My age is %d and no is %d”,age,no];
③ 查看字符串长度(length计算的是字数):int size =[str length];
2、类的独立抽取:
1> 使用注意:
① 只有类名调用类方法时,不需在类名后写*;其他情况下,类名后统一加上*;
② 返回值是BOOL类型的方法,方法名一般都以is开头;
③ 想要拥有某个对象,就先创建对象,然后调用set方法将对象传递给内部的成员变量;
2> 定义一个类需定义2个文件:一个.m文件(方法的实现)和一个.h文件(成员变量、方法的声明);
3> 若想使用某个类,只需#import类的.h文件(如: #import “Car.h”);
3、XCode功能展示:
1> 使用#pragma mark 哈哈/#pragma mark - 哈哈 在每个对象实现方法前标记注释;
(二)面向对象-核心语法
1、 点语法:
1> 本质:方法的调用(例:[p setAge:20]èp.age = 20);
2> 注意:① 法不是访问对象的成员变量;
② set方法中使用self.age=age与get方法中使用return self.age会引发死循环;
2、 成员变量的作用域:(@interface中成员变量默认为protecated;@implementation中成员变量默认为@private)
1> @public:任何地方都可直接访问对象的成员变量;
2> @package:可同一个“体系内”(框架)可访问,介于@private和@public间;
3> @protecated:可在当前类和子类的对象方法@implementation中直接访问;
4> @private:只能在当前类的的对象方法@implementation中直接访问;
5> 使用注意:
① 类的实现中(.m文件中)@implementation中定义成员变量,默认为@private(即使修改为@public,但其它类也无法访问);
② 类的实现中@implementation中不能定义和@interface中同名的成员变量;
③ @implementation使用:即使没有@interface,只有@implementation也可开发一个类;
3、 @property和@synthesize的使用
1> 使用@property可自动生成带下划线的私有成员变量及该成员变量的setter和getter声明(@property int age;);
2> 使用@synthesize可自动生成某个成员变量的setter和getter的实现并且会访问_age这个成员变量(@synthesize age=_age;_age为指明成员变量(默认访问age),相同类型也可续写@synthesize age=_age,weight=_weight;);
3> @synthesize细节:
@synthesize age=_age;会访问_age这个成员变量,若不存在会自动生成@private类型的_age;
4> XCode4.4后,@property就独裁了@synthesize的功能,就是说:可直接使用@property自动生成一个带下划线的@private成员变量及该成员变量的setter和getter声明和实现;
5> @property只能使用在@interface中,@synthesize只能使用在@implementation中;
6> @synthesize使用注意:
① 若手动实现setter方法,编译器就只会自动生成getter方法和不存在的成员变量;
② 若手动实现getter方法,编译器就只会自动生成setter方法和不存在的成员变量;
③ 若同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量;
4、 Id的使用:
1> 万能指针,能操作/指向任何OC对象,但id后面不加*)(如:id d = [Person new]) 2> id ==>NSObject *;
5、 构造方法(用来初始化对象的方法,是个对象方法,减号开头):
1> 完整的创建一个可用的对象(new方法,如: Person * p = [Person new];==>Person * p = [[Person alloc] init];):
① 分配存储空间(类方法):+alloc(如: Person * p1 = [Person alloc];);
② 初始化(对象方法):-init(如:Person *p2 = [p1 init];);
2> 使每个Person对象创建出来,他的_age都是10:
① 在@implementation中重写-init方法:
-(id)init
{
//1.一定要调用super的init方法:初始化父类中声明的一些成员变量和其它属性;
//self = [super init]; //返回当前对象self
//若对象初始化成功,才有必要进行接下来的初始化;
if(self = [super init] ){
//self!=nil则初始化成功
_age = 10 ;
}
return self; //返回一个已经初始化完毕的对象;
}
② 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值;
③ 重写构造方法注意点:
。先调用父类的构造方法([super init]);
。再进行子类内部成员变量的初始化;
3> 组合:在Person类中:@property Body* body;
6、 自定义构造方法(@implementation中):
1> 自定义构造方法规范:
① 一定是对象方法,一定以减号开头;
② 返回值一般是id类型;
③ 方法名一般以initWith开头;
//多个变量自定义:- (id) initWithName:(NSString *) name andAge:(int)age
- (id) initWithName:(NSString *) name
{
if(self = [super init] )
{
_name = name ;
//_age = age;
}
return self;
}
2> 父类的属性交给父类方法去处理,子类的属性子类方法去处理;
7、 分类的使用:
1> 分类:可给某个类扩充一些方法(不修改原来类的前提);
2> 声明:@interface 类名(分类名称)@end
3> 实现:@implementation 类名(分类名称) @end;
4> 作用:在不改变原来类内容的基础上,可为类增加一些方法;
5> 使用注意:
① 分类不能扩充成员变量,只能扩充方法;
② 分类方法实现中可访问原来类中声明的成员变量;
③ 分类可重新实现原来类中的方法,但会覆盖掉原来的方法,会导致原来的方法没法再使用;
④ 方法调用优先级:优先去分类(最后参与的分类优先)中查找à原来的方法中查找à父类中查找;
6> 分类给NSString增加类方法
① 例:在一个字符串中查看包含几个阿拉伯数字
+(int)numberCountOfString:(NSString *)str
{
//定义变量计算数字个数
int count = 0;
for(int i = 0 ; i < [str.length]; i ++)
{
unichar c = [str characterAtIndex:i];
if(c >=’0’ && c<= ‘9’)
{
Count++;
}
}
return count;
}
提示:调用:int count =[NSString numberCountOfString:@”yyy222mm”];
② 例:给当前字符串中查看包含几个阿拉伯数字
- (int) numberCount
{
int count = 0;
for(int i = 0;i<self.length;i++)
{
//取出i这个位置对应的字符
Unichar c = [self characterAtIndex : i];
//若这个是阿拉伯数字
if(c >=’0’ && c<= ‘9’)
{
Count++;
}
}
return count;
}
提示:调用:int count = [@”yyyy23mmm” numberCount];
8、 类的深入研究:
1> 类的本质:类本身也是一个对象,是个class类型的对象,简称类对象/类;
2> 每个类只有一个类对象;
3> 获取内存中的类对象:class c = [p class];
4> 类的加载(只调用一次):在类加载时(当程序一启动)系统会加载项目中所有的类和分类(不管有没有使用),类加载完毕后系统自动调用父类的+(void)load,再加载子类的load方法;
5> (可用来监听类)类的初始化:当第一次使用某个类时(Person init方法调用时)就调用父类的+(void)initialize方法,再调用子类的initialize方法;(一个类只会掉用一次initialize方法)
9、 Description方法:
1> 使用NSLog(@“%@”,p)来输出对象是,结果是<类名:内存地址>;
① 会调用对象p的-description方法;
② 拿到-description方法的返回值(NSString *)显示到屏幕上;
③ -description方法默认返回的是“类名+内存地址”;
④ 若不打印默认的内存地址,则在@implementation中重新实现-(NSString *)description{ //若使用NSLog(@“%@”,self)会引发死循环; return [NSString stringWithFormat:@”age=%d,name=%@”,_age,_name];}来输出成员变量值;
⑤ 使用-(NSString *)description决定了实例对象的输出结果;
使用+(NSString *)description{}决定了类对象的输出结果;
2>
10、 NSLog使用:
1> 指针变量的地址:NSLog(@“%p”,&p);
2> 对象的地址:NSLog(@“%p”,p);
3> <类名:对象地址>:NSLog(@“%@”,p);
4> 输出源文件名称:NSLog(@”%s\n”,_FILE_)èprint(“%s\n”,_FILE_);(NSLog输出C语言字符串时,不能有中文);
5> 输出当前函数名:NSLog(@”%s”,_func_);
6> 输出行号:NSLog(@”%d”,_LINE_);
11、 SEL的使用(SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可调用方法。其实消息就是SEl):
1> 方法存储位置:
① 每个类的方法列表都存储在类对象中;
② 每个方法都有一个与之对应的SEL类型的对象;
③ 根据一个SEL对象就可找到方法的地址,进而调用方法;
④ SEL类型的定义:typedef struct objc_selector *SEL;
2> SEL对象的创建:
① SEL s = @selector(test);
② SEL s2 = NSSelectorFromString(@”test”);//将NSString对象转为SEL对象;
3> SEL对象的其它用法:
//将SEL对象转为NSString对象
NSString *str = NSStringFromSelector(@selector(test));
Person *p = [Person new];
//调用对象p的test方法
[p performSelector:@selector(test)];
//注意,调用[self performSelector:_cmd ]会引发死循环;
4> _cmd代表当前方法(_cmd==@selector(test)):NSString *str = NSStringFromSelector(_cmd);
------- android培训、iOS培训、Java培训、.NET培训期待与您交流! ----------