------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1.点语法
- (void)setAge:(int)age
{
//_age = age;
NSLog(@"setAge:");
// 会引发死循环
//self.age = age; // [self setAge:age];
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
- (int)age
{
NSLog(@"age");
return _age;
// 会引发死循环
//return self.age;// [self age];
}
2.成员变量的作用域
1)成员变量的四种作用域
1>@public : 在任何地方都能直接访问对象的成员变量
2>@private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private)
3>@protected : 可以在当前类及其子类的对象方法中直接访问 (@interface中默认就是@protected)
4>@package : 只要处在同一个框架中,就能直接访问对象的成员变量
#import
@interface Person : NSObject
{
int _no;
@public // 在任何地方都能直接访问对象的成员变量
int _age;
@private // 只能在当前类的对象方法中直接访问
int _height;
@protected // 能在当前类和子类的对象方法中直接访问
int _weight;
int _money;
}
1> @interface和@implementation中不能声明同名的成员变量。
2>在类的实现中定义的成员变量默认是私有的。
3> @implementation中不能定义和@interface中同名的成员变量
3.@property 和 @synthesize
1) @property:可以自动生成某个成员变量的setter和getter声明
#import
@interface Person : NSObject
{
int _age;
int _height;
double _weight;
NSString *_name;
}
// @property:可以自动生成某个成员变量的setter和getter声明
@property int age;
//- (void)setAge:(int)age;
//- (int)age;
@property int height;
//- (void)setHeight:(int)height;
//- (int)height;
@property double weight;
@property NSString *name;
@end
#import "Person.h"
@implementation Person
// @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量
@synthesize age = _age;
@synthesize height = _height;
@synthesize weight = _weight, name = _name;
@end
1>会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量
#import "Car.h"
@implementation Car
@synthesize speed = _speed;
2>默认会访问age这个成员变量,如果没有age,就会自动生成@private类型的age变量
@implementation Cat
@synthesize age;
@end
3>自从Xcode4x以后,@property 就独揽了@synthesize的功能,也就是说@property 可以同时生成setter和getter
4>默认情况下。setter和getter方法的实现,会访问下划线开头的成员变量。
4.id 万能指针
1)简介
万能指针,能指向\操作任何OC对象(id == NSObject *)
NSObject *o = [Person new];
id d = [Person new];
2)使用注意:id后面不要加*
3)调用一个不存在的方法编译器会报错
5.构造方法
用来初始化对象的方法,是个对象方法,-开头
重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
1.分配存储空间 +alloc
2.初始化 -init
// 1.调用+alloc分配存储空间
// Person *p1 = [Person alloc];
// 2.调用-init进行初始化
// Person *p2 = [p1 init];
3)使用构造方法注意点
1>先调用父类的构造方法([super init])
2>再进行子类内部成员变量的初始化
4)重写init方法
- (id)init
{
if ( self = [super init] )
{ // 初始化成功
_age = 10;
}
// 3.返回一个已经初始化完毕的对象
return self;
}
1.一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性
2.如果对象初始化成功,才有必要进行接下来的初始化
3.返回一个已经初始化完毕的对象
5)构造方法内存解析图
自定义构造方法的规范
1.一定是对象方法,一定以 - 开头
2.返回值一般是id类型
3.方法名一般以initWith开头
假如子类需要写的构造方法用到父类的构造方法时间
父类的属性交给父类方法去处理,子类方法处理子类自己的属性
6.Category-分类
分类的作用:在不改变原来类内容的基础上,可以为类增加一些方法
使用注意:
1.分类只能增加方法,不能增加成员变量
2.分类方法实现中可以访问原来类中声明的成员变量
3.分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用
4.方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类 --> 父类
分类的应用
给NSString增加一个类方法:计算某个字符串中阿拉伯数字的个数
给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
++++++++++NSString+Number.h++++++++++++++++++++++++++++
#import
@interface NSString (Number)
+ (int)numberCountOfString:(NSString *)str;
- (int)numberCount;
@end
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++ NSString+Number.m+++++++++++++++++++++++++++++++++++++
#import "NSString+Number.h"
@implementation NSString (Number)
// @"abc434ab43"
+ (int)numberCountOfString:(NSString *)str
{
// 1.定义变量计算数字的个数
// int count = 0;
//
// for (int i = 0; i
='0' && c<='9')
// {
// count++;
// }
// }
// return count;
return [str numberCount];
}
- (int)numberCount
{
int count = 0;
for (int i = 0; i
='0' && c<='9' )
{
count++;
}
}
return count;
}
@end
++++++++++++++++++++++ main.m+++++++++++++++++++++++++++++++++++
#import
#import "NSString+Number.h"
int main()
// 类库:很多类的集合
{
// int count = [NSString numberCountOfString:@"54d43a43s43dasd"];
int count = [@"9fdsfds543543" numberCount];
NSLog(@"%d", count);
return 0;
}
7.类的本质
1)内存中的类对象(类对象 == 类):类本身也是一个对象,是个Class类型的对象,简称类对象。
2)类的加载和初始化
1>当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。
2>当第一次使用某个类时,就会调用当前类的+initialize方法
3>先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)
先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)
8.description方法
默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>
1>.会调用对象p的-description方法
2>拿到-description方法的返回值(NSString *)显示到屏幕上
3>-description方法默认返回的是“类名+内存地址”
输出行号
NSLog(@"%d", __LINE__);
NSLog输出C语言字符串的时候,不能有中文
输出源文件的名称
printf("%s\n", __FILE__);
Person *p = [[Person alloc] init];
// 指针变量的地址
NSLog(@"%p", &p);
// 对象的地址
NSLog(@"%p", p);
// <类名:对象地址>
NSLog(@"%@", p);
决定了实例对象的输出结果
- (NSString *)description
{
// 下面代码会引发死循环
// NSLog(@"%@", self);
return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];
}
9.SEL
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法,其实消息就是SEL。
_cmd代表着当前方法
NSString *str = NSStringFromSelector(_cmd);
会引发死循环
[self performSelector:_cmd];
1.把test2包装成SEL类型的数据
SEL s = @selector(test3:);
2.根据SEL数据找到对应的方法地址
[p performSelector:s withObject:@"456"];
3.根据方法地址调用对应的方法
[p test2];
10.Xcode 的模板路径
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates
* File Templates 文件模板:可以修改类文件等
* Project Templates 项目模板:可以修改一些项目描述