1. NSString前面NS是NextSTEP的缩写.
2.面向对象编程OOP (ObjectOrientedProgramming)
3.接口在程序里叫数据接口
在网络里叫网络接口
4.成员可见度定义:
@public大家的
@product受保护的
@private私有的
5.接口部分标志@interface@end一对
6.所有@的符号都是OC对C语言扩展的东西
7.
-(void)sayHi; -号代表实例方法.void是返回值类型.
+类方法.
8.
-号方法必须由实例对象来调用,+号方法必须由类来直接调用
9.NSLog=printfNSLog是C语言的函数
10.NSLog(@“sdfsdfsdf”);@后面叫字符串对象. %@替换对象的(替换进去的肯定是文字信息)
112015-01-22 16:32:33.758 HelloOC[618:303]HELLO, WORLD
618是进程号,303线程号
12.
类名大写开头
方法名和变量小写开头
13 #import导入oc基础库
14具有相同特征和行为的事物的抽象.类的定义
15所有的类都放在了全局区
alloc是把在全局去里的成员变量拷贝到堆里面一份
alloc所有的成员变量都有初值
16 void *p无类型指针
17id是typedefvoid *id叫泛型指针id可以保存任何类型的指针.
17不能简单的改变2个变量的值,而作用域约束
如果想在外部去修改2个局部变量的值,必须拿到地址.
18->指向标示符
19父类:总类子类:分类的概念.而不是父亲和儿子的概念(不是具体的实物)!
20给对象声明空间的时候就赋初值
Person.h中:
@interface Person :NSObject
{
@public//如果下面没给值,系统会自动初始化.
NSString *_name;
NSString *_gender;
NSString *_hobby;
NSString *_hobby1;
int _age;
}
- (id)init1;
@end
Person.m中:
- (id)init1
{
_age = 18;
_name = @"HAHAHA";
return self;
}
main.m中:
Person *p =[[Person alloc] init1];
[p eat];
可见度是约束(标示符)的访问权限,指的是标示符符号的访问权.
21
@public子类可见,外部也可见
@protected子类可见,外部不可见
@private子类不可见(不允许访问),外部类不可见
子类可以继承父类的private后的属性,但是不能访问.
private不光要保护内部数据的安全,也要保护外部能安全的使用.
22.在当前类中不允许方法名重复,在别的类可以定义一个跟这个方法同名的方法.
-(id)initWithName:(NSString *)name;init开头是对创建对象和初始化的,不要随便写类名字开头.如果init不是初始化的方法,Xcode会拒绝编译.
初始化方法init只能调用一次.不能重复调用
- (void)setName:(NSString*)name setGender:(NSString *)gender
{
_name = name;
_gender = gender;
}
但是不能同时get2个属性例如:
- (NSString*)getName: (NSString *)getGender
{
return self;
}这样是错误的
如果不小心修改了Xcode的系统文件.
找到错误提示路径,删除里面所有东西,之后再Xcode中Product中选择clean然后在重新编译.
不能在main里面用super因为main类没有父类.
对super发消息就是一个途径,指向的从父类继承的方法.
构造器用来创建对象的
重点:指派构造designated
initializer指派初始化方法.
(某个方法里面有super init那么这个方法就是指派构造化方法.(也是初始化入口)(也叫默认指派初始化方法)
类里面必须得有这么唯一一个指派初始化方法的入口
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
hobby:(NSString *)hobby
{
//self = [super init];
//if (self) {
//_name = name;
//_sex = sex;
//_hobby = hobby;
//}
//return self;
self = [self initWithName:name sex:sexhobby:hobby age:0];
return self;
}
指派初始化方法:
- (id)init
{
//self = [super init];
////如果self是有效指针(非空)
//if (self) {
//_name = @"小唐";
//_sex = @"男";
//_age = 40;
//}
self = [self initWithName:nil sex:nilhobby:nil age:0];
return self;
}
- (id)initWithName:(NSString*)name
{
self = [self initWithName:name sex:nil];
return self;
}
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
{
self = [self initWithName:name sex:sexhobby:nil];
return self;
}
- (id)initWithName:(NSString*)name
sex:(NSString *)sex
hobby:(NSString *)hobby
{
self = [self initWithName:name sex:sexhobby:hobby age:0];
return self;
}
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
hobby:(NSString *)hobby
age:(NSInteger)age
{
self = [super init];
if (self) {
_name = name;
_sex = sex;
_hobby = hobby;
_age = age;
}
return self;
}
dealloc(销毁)不允许手动调用,系统自动调用
MRC manual
reference count手动引用计数
ARCauto reference count系统自动扫描添加释放内存.
-release()是引用计数器减1
-autorelease()自动释放池.
-retain(引用,不会产生新的对象)对这个对象发送这个消息,引用计数器+1
[sturetainCount]输出引用计数器的值
怎么把Xcode改成MRC
左键项目,然后搜matic找到objective-c
automatic reference counting改成no
alloc和retain的数量要等于release
便利构造器:
+
(id)personWithName:(NSString *)name//+开头,类名开头,返回的是id就是便利构造器
{
Person *person = [[Person alloc]initWithName:name];
return [person autorelease];
}
autorelease自动释放池,什么时候释放,是由系统控制的
//为什么释放之后还是能打出来1:
Person *per = [PersonpersonWithName:@"小唐"];
NSLog(@"%lu",[per retainCount]);
[per release];
NSLog(@"%lu",[perretainCount]);//这个是野指针,虽然对象被释放了,但是内存那块没被覆盖,所以才能打出来1.
系统为了做优化,所以当retainCount为1的时候直接销毁,不用再去—了.
- (void)release
{
if (1== self.retainCount) {
[self dealloc];
}
else {
self.retainCount--;
}
}
autorelease引用计数器延迟减1
成员变量是随着对象消亡而消亡对象的消亡是在dealloc中,每个成员变量要在dealloc这释放.
栈里面的东西是随着函数的退出而消亡
当指针变量声明周期结束前要release
settergetter方法,和便利构造器补全.
父对象要保证子对象在父对象的生命周期是安全的
比如myclass是父对象(_student这个指针指向的那个student就是子对象),里面有个Student*student这个student是子对象.(因为student是个指针也是个对象)
如何保证父对象里的子对象安全,对子对象retain.
为什么不能手动写dealloc因为可能还有别人在用,释放了的话就crash了
在.h中容易产生交叉导入,容易产生符号找不着的问题.
而真正的头文件要在.m中导入.
父对象一定会强引用自己的子对象.(强引用,就是对引用计数器+1)
self是内部指向这个类的指针,stu是外部的指针
atomic(原子)原子化效率低,安全
一个类可以写在不同的原文件中.(类目)
只能添加方法,不能添加成员变量.
@interface NSString(SayHi)给NSString添加一个SayHi
方法.
当两个对象都同时要使用同一个字符串的时候,这个字符串类型要用NSMutableString
指针类型的作用:
1.做算术运算跳数的大小
2.间接寻址指向的类型.
NSString *p方便编译器去检查错误(为什么加指针符号
如果想让类目访问成员变量,必须在主类里显示声明.
isEqualToString比较两个字符串对象是否相等\
怎么把数字转换成字符串.
OC的数组会对每一个加进去的对象,引用计数器都会+1,然后释放的时候,会自动减1.
//其实自动释放池里就有一个数组
self只能初始化才能赋值,以后就不能变了.
字典存取不是连续的,是散列的,根据key所计算的下表(哈希算法)
字典以空指针结束.所以不能存空指针
//71 72 74
//26 27 30 313237
(集合)set无序集合.直接给一个对象,自动算hash.(当你需要知道一个对象是否在集合中) (集合和数组和对象不同,不能存重复对象)
假设hash重复了,就顺延往下存,第二种就是往上跳10个.
第三种,做小集合,如果在这个小集合找到重复的了,就去另一个小集合找.
netsh winsock reset
super只能帮我们找到这个类从父类继承过来的方法.
指针声明周期结束之前要对它relase
局部变量在消亡时释放?
成员变量在函数return时释放?
id是泛型指针,(可以保存任意类型的指针)
添加到数组中得元素都会retain
遍历构造器的好处:
1.工厂方法,工厂生产
2.我们不用关系它的释放,因为返回回来的就是临时对象!
加完断点之后,在lldb中输入po province打印这个对象.
子对象强引用父对象,形成内存空洞.都互相对对方引用计数器+ 1
嵌套引用(2个对象无法释放)
类目
不能增加成员变量.(如果在类目中添加属性,只有方法,没有对应的成员变量).(类目不能访问属性创建的成员变量)
分类管理类
写在不同的原文件中
额外添加相应方法
时间戳(1970年开始计算秒数):因为1970年Unix
NSDate存得的是标准时间,没有时差.
//NSTimeZone *zone = [NSTimeZonetimeZoneWithName:@"America/Swift_Current"];
//[nmatter setTimeZone:zone];
//NSDate *sDate = [nmatterdateFromString:dateString];
//NSLog(@"%@", sDate);
OC的类目是为了防止java的过度继承
OC中写入延展是对类内部开放的,不让外面类访问(也就是java中得私有方法.)
有效的封装不只是保证内部安全,还保障外部安全.
接口是对外服务的菜单
私有API方法是在延展里的,没有在.h中声明的
协议里的可选方法,(首先要确定这个方法实现了)
一个类可以遵守多个协议(协议是可以继承的)
代理指针为什么用assign,不允许用retain为了防止父对象做子对象的代理时候,产生的循环应用.
(延展):把外面不需要的功能,放在类里面(高内聚)
(协议):每个类单独管理,而不是两个类互相有联系(低耦合)
//alloc, copy, init产生的对象不需要释放.(这3个单词不能做字头)
浅拷贝:父对象是同一个,子对象是不同的
深拷贝:父对象和子对象是不同的2对
父类指针指向了子类对象(多态) (目的:写通用代码);
setter和getter里面写得先得判断传进来是不是以前的.
block就是一段代码段,(访问得用指针访问) block就是一个对象,可以retain和copy