ios OC初学

OC源文件后缀名为m,代表OC中最重要的一个机制:消息机制。
OC程序的入口与出口仍然是main函数
OC支持C中的所有关键字、运算符、控制语句、函数
OC语言完全兼容C语言

import即#include的增强版

同一个文件无论#import多少次,始终导入一次

NSLog是一个函数:

printf的增强版,想控制台输出信息;
NSLog(@”hello world”);
执行结果包括:
当前执行时间、程序名、进程编号、线程编号、程序执行信息
用法和printf相同、只不过前面要加@
NSLog的输出是自动换行的,如果加上了\n,那么NSLog的自动换行就会失效

字符串

OC中设计了一个更为好用的用来存储字符串的NSString类型
NSString类型的指针变量 专门用来存储OC字符串的地址
使用NSLog输出OC字符串的占位符为 %@

编辑、编译、链接

cc -c xx.m

链接
cc xx.o
如果用到了框架
cc xx.0 - [framework framework_name]

新增的布尔型变量

BOOL只有两个值:YES/NO
Boolean的值为true/false

面向对象

类的声明

@interface className : NSObject
{
  变量
}
@end

为类定位属性时,属性的名词必须以下划线开头
类的方法的声明应写在interface中
属性不允许在声明的时候初始化

类的实现

@implementation className
@end

类名的每一个单词的开头必须以大写开头
类方法的实现应写在implementation中

类的实例化

对象中除了成员变量外,还有一个isa指针,该指针指向代码段中该类所属的类
当调用函数时,指针名先找到对象,当发现要调用函数时,就根据isa指针寻找该对象所属的类

对象属性的默认值

基本数据类型 0
C指针类型 null,可以作为指针变量的值,不指向任何一个区域,NULL其实等价于0,就是一个宏
OC指针类型 nil 可以作为指针变量的值,不指向任何一个区域,NULL其实等价于0,就是一个宏

nil == null 但是一般建议C指针用null,OC的类指针用nil

函数除了在函数的内部和和interface的大括弧中,其他地方都可以写

类的实现可以放在使用类的后面

类方法声明和实现时除了格式上

+ (return类型) functionName:[(数据类型) 形参名称]

其他与普通方法无异

self相当于C/C++中的this指针,self指向该对象/类在代码段中的地址

加载类

第一次访问类时
第一次使用类时

类中继承自NSObject的方法 - (NSString *) description{} 就相当于java中的toString方法

访问权限问题

@private 只能在本类内部以及本类的方法实现中访问
@public 只能在本类和本类的子类中访问
@package 只能在当前的框架中访问

点语法

OC中的点语法与Java、C#中的不同,OC中点语法默认调用程序员自己封装好的setter和getter函数,那么我们再setter、getter方法中就不能用点语法对类属性进行赋值、防止无限递归

getter和setter方法的自动生成

@property 数据类型 属性名

在interface中书写左侧语句则由编译器自动生成对应属性的getter和setter方法的声明,但是此处属性名为真实属性名去掉下划线,否则自动生成的方法声明是不符合规范的
@synthesize 属性名
同样的,在implementation中书写上述代码,则自动生成对应的getter和setter方法的实现

但是他们的实现都是默认自动生成一个私有的具有上述属性名的属性,如果需要生成对应的已经声明的属性的getter和setter方法,只需要书写如下

@property 数据类型 属性名 = _属性名
@synthesize 属性名 = _属性名
@property(nonatomic/atomic,retain/assign,readwrite/readonly)
//nonatomic不会自动加线程安全锁
//retain生成setter方法的时候先判断新的是否等于旧的,如果不等于则先进行release再进行retain
//readwrite同时生成setter和getter
//readonly只生成getter
@property(nonatomic,retain,setter = xxx,getter = xxx)
//指定setter和getter方法的名字

测试指向对象的指针是否有某方法

responseToSelector:@selector(SEL)

判断某指针指向的对象是否为某类的对象或其子类的对象

isKindOfClass: [className class]
isMemberOfClass: [] 判断是否为对象
isSubclassOfClass: [] 是否为子类对象

分组导航标记

pragma mark 分组名 就会在导航条对应位置显示一个标题
pragma mark - [分组名] 就会在导航条对应的位置显示一条水平分隔线

继承

OC中只有单根继承,没有多继承

类方法也能被子类继承,被继承的类方法可以用子类名继承,也可以用父类名继承

super只能用来调用父类方法,不能用来调用属性

里氏替换原则(LSP):子类可以替换父类的位置,程序功能不受影响,但是指向子类对象的父类指针无法调用子类特有的方法和属性

多态

指向重写了父类方法的子类对象的父类指针,被调用时,执行的是子类重写了的方法

id指针

id指针是一个万能指针,可以指向任意OC对象
NSObject *也是一个万能指针
但是使用id调用方法时,编译器直接同构,使用NSObject指针时,编译器会做编译检查
id指针只能调用对象的方法,不能使用点语法,如果使用点语法就会直接报错。

内存中的五大区域

存储局部变量

程序员手动申请的字节空间 malloc、calloc、realloc函数

BSS段

存储未被初始化的全局变量、静态变量

数据段

存储已被初始化的全局、静态变量、常量数据

代码段

存储代码

retainCount

每个对象都有一个retainCount引用计数器
retain信号 即retainCount++
release信号 即retainCount–

内存泄漏

在方法中为传入的对象进行不适当的retain,就造成没有适当的release

setter方法内:
- (void) setCar:(Car *car)
{
  if(_car != car)
  {
    [_car release];
    _car = car;
  }
}
//

野指针、僵尸对象

野指针:指针指向的对象已经被分配给别人
僵尸对象:对象已被释放、但是这个对象占有的空间还没被分配给别人,僵尸对象无法被复活

僵尸对象检查机制

Enable Zombie Objects 但是每当用到指针的时候,都会进行僵尸对象检查,所以这非常消耗性能,那么该如何避免僵尸对象错误呢,当一个指针成为野指针以后,将这个指针的值设置为nil

强指针

平常情况下声明的一个指针就是强指针
在ARC的机制下,如果一个对象没有任何一个强指针指向他,就会被立即释放
也可以用_ strong、 _weak分别声明强指针和弱指针

ARC机制下

某对象被释放后、原来指向这个对象的弱指针自动被设置为nil
@property中的retain参数不能用
####ARC机制下的使用建议
如果是OC对象类型,就用strong,不是OC对象类型就用assign
存在类间属性互相引用的情况下,一端使用weak,一端使用strong

将整个程序从MRC转换为ARC: Edit—Convert

分类

    @interface 类名 (分类名) : 父类
    @end
@implementation 类名 (分类名)
@end

但是在分类中只能增加方法,不能增加属性
如果分类中有和本类同名的方法,则优先调用分类中的方法,哪怕没有调用分类的同文件
如果多个分类有同名的方法,则调用最后编译的那个分类中的方法
###分类高级(非正式协议)
既然优先调用分类的方法、那我们就可以在某些层面上“篡改”apple公司已经编好的、令人不爽的方法,只需要为该类建立一个分类,并在分类中“篡改”或添加自己想要该类拥有的方法即可

延展

延展是一个特殊的分类,只有声明、没有实现,和本类共享一个实现
延展可以新增任意的成员属性,也可以写@property,既生成私有属性,也生成setter、getter方法的声明和实现
用延展来为类写真私有属性
也可以将私有方法的声明写在延展中,实现写在本类的实现当中,提高代码的可读性
延展天生就是用来私有化成员的

block

与C中的函数类似
##block高级
将block作为参数传入
将block做返回值返回

协议(protocol)

协议专门用来声明一大堆方法,只要某类遵循某个协议,那么这个类就拥有该协议的所有方法
某类遵循某协议的语法:
@interface className : 父类名

@required和@optional

@required表示如果遵守该协议的类没有实现,编译器就会报警告
@optional表示如果未遵守该协议的类没有实现,编译器不会报警告
但是没有关系,”反正只是警告而已”

协议之间可以继承、并且可以多继承

继承语法

@protocol protocolName <父协议名>
@end

类的名称可以和协议的名称一致

异常处理

@try
{
  可能出现异常的代码段
}
@catch(NSException *exc)
{
  对异常的处理
}
@finally
{
  此处无论是否发生异常都会被执行到
}

自动释放池@autoreleasepool

最高法则:唯一的作用就是省略创建对象匹配的那个release

如果A类是B类的参数,那么称B类依赖于A类

多线程

NSThread

Swift

常量&变量

let定义常量,var定义变量

自动推导

会根据设置数值的右侧代码,推断变量/常量的类型

永远不会对变量/常量做隐式转换,所以两个不同类型的变量计算的时候,必须全权由程序员来做类型管理(强制转换)

可选项

一个变量可以是本身的类型,也可以是nil
var y: Int ?= 10
可选项不能直接参与计算,但是可以“强行解包”
print( y! + 20)
就是添加惊叹号,表示:程序员承诺y一定是有值的,如果没有,就在运行时候崩溃给我看

控制流

条件

if 条件 {
  expression;
}

if后没有圆括号,但是语句必须有花括弧
switch可以判断任意类型的数值,而且不需要break,各个case之间不会穿透,如果相对多个case执行同一个决定,只需要在case后面的值加逗号即可,不需要使用花括弧分隔作用域

字符串

substringWithRange(Range类型)
[int]..<[int] 用来定义一个范围

数组


array.append()

array.removeFirst()
array.removeLast()
array.removeAll()

array[i] = sth

约定俗成

单参数的函数名称最好写成xxxWith
一个类写在一个模块中,一个模块至少包含两个文件.h写类的声明 .m写类的实现
如果创建了一个类,就要为该类写一个与类同名的类方法,方法实现创建一个最纯洁的类并返回
属性名要求以下划线开头,局部变量不要求。故一般不会产生局部变量与类属性重名的情况
所有协议都必须直接或间接地从NSObject基协议继承

小技巧

  • 隐藏顶部状态栏
- (BOOL)prefersStatusBarHidden
{
    return true;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值