一、成员变量的作用域

  • @public
    • 在任何地方都能直接访问对象的成员变量
  • @private
    • 只能在当前类的对象方法中访问
  • @protected(可以不写,默认)
    • 能在当前类和子类的对象方法中直接访问
  • @package
    • 只要处在同一个框架中,就能直接访问对象的成员变量
  • @interface和@implementation中不能声明同名的成员变量
  • 在@implementation中声明变量,默认是@private的

二、点语法

  • 点语法的本质还是方法调用,不是调用成员变量
  • 编译器遇到点语法时,会把点语法转成方法
1
2
3
p.age = 10;         //[p setAge:10];
 
int age = p.age;    //[p age];

三、构造方法

  • 用来初始化对象的方法,对象方法,以减号开头
  • 为了让对象创建出来,成员变量就会有一些固定的值
  • 重写构造方法的注意点:
    • 先调用父类的构造方法([super init])
    • 再进行子类内部成员变量的初始化
  • + alloc 方法
    • 分配存储空间
  • - init 方法
    • 初始化
  • 实际上是这么创建对象的
1
Person *p5 = [[Person alloc] init];    //先分配存储空间,再进行初始化
  • 重写NSObject类的init方法(无参数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (id)init
 
{
 
    //一定要调用回super得init方法:初始化父类中声明的一些成员变量和其他属性
 
    if (self = [super init]) {
 
        //初始化成功
 
        _age = 10;
 
    }
 
    return self;  
 
}
  • 带参数的构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (id)initWithName:(NSString *)name andAge:(int)age
 
{
 
    if (self = [super init]) {
 
        _age = age;
 
        _name = name;
 
    }
 
    return self;
 
}

四、分类

  • 分类,在不改变原来模型的情况下,可以给某个类扩充一些方法
  • 分类只能增加方法, 不能增加成员变量
  • 分类方法实现中可以访问原来类中声明的成员变量
  • 分类的优先级最高,方法优先去分类中去找,再去原来类中去找,最后再去父类中找
  • 分类可以重写原来类中的方法,但是会覆盖掉,会导致原来的方法失效,没法再使用
  • 方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类 --> 父类
  • 分类的应用一般是扩展系统的类的方法,比如扩展NSString类的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
+ (int)numberCountOfString:(NSString *)str
 
{
 
    int count = 0;
 
    for (unsigned long i = 0; i < [str length]; i++) {
 
        unichar ch = [str characterAtIndex:i];
 
        if (ch >= '0' && ch <='9') {
 
            count++;
 
        }
 
    }
 
     
 
    return count;
 
    //return [str numberCount];
 
}
 
 
 
 
 
//计算某个字符串中阿拉伯数字的个数(对象方法)
 
- (int)numberCount
 
{
 
    int count = 0;
 
    for (unsigned i = 0 ; i < [self length]; i++) {
 
        unichar ch = [self characterAtIndex:i];
 
        if (ch >= '0' && ch <='9') {
 
            count++;
 
        }
 
    }
 
     
 
    return count;
 
    //return [NSString numberCountOfString:self];
 
}

五、类的本质

  • 可以使用类创建对象,但是类本身也是一个对象,是个Class类型的对象,简称“类对象
  • 先利用Class创建一个Person类对象,再利用Person类对象,创建Person类型的对象
  • 重写load()方法和initialize()方法
1
2
3
4
5
6
7
8
9
10
11
+ (void)load
{
    NSLog(@"Student的load方法被调用");
}
 
//在第一次被使用的时候就会被调用一次,监听类第一次被使用的时候
 
+ (void)initialize
{
    NSLog(@"Student-initialize方法被调用");
}
  • load()方法:
    • 当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的load方法。只会调用一次
    • 当第一次使用某个类时,就会调用当前类的+initialize方法
    • 先加载父类,再加载子类(先调用父类的load方法,再调用子类的load方法)
    • 先初始化父类,再初始化子类(先调用父类的initialize方法,再调用子类的initialize方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//利用Person这个类创建了3个Person类型的对象
Person *p = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
Person *p3 = [[Person alloc] init];
 
//先利用Class创建一个Person类对象   
//再利用Person类对象,创建Person类型的对象
//获取内存中的类对象
Class c = [p class];
Class c2 = [p class];
 
//获取内存中的类对象
Class c3 = [Person class];
NSLog(@"c=%p,c2=%p,c3=%p",c,c2,c3);  //c的地址等于c2,也等于c3
 
//程序先加载父类,再加载子类,而且类只被加载一次
//只要加载了类,就会调用load类方法
//initialize类方法是在类第一次被初始化时,被调用,如果在使用子类的时候,父类也会被调用该方法
//分类也会被加载,如果原始类和分类都重写了initialize方法,那么分类的initialize方法优先被调用,原始类不调用
GoodStudent *stu = [[GoodStudent alloc] init];

六、自动生成getter和setter方法

  • @property自动生成某个成员变量的声明
  • @synthesize自动生成getter和setter的实现,并且会访问指定的成员变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//自动生成某个成员变量的声明
//编译器特性:编译器当遇到@property时,自动转换成setter和getter声明方法
// - (void)setAge:(int)age;
// - (int)age;
@property int age; //生成_age成员变量
@property double height; //生成_height成员变量
@property double weight; //生成_weight成员变量
@property NSString *name;    //生成_name成员变量
 
//@synthesize自动生成getter和setter的实现,并且会访问指定的成员变量
@synthesize age = _age;
@synthesize height = _height;
//用逗号分隔
@synthesize weight = _weight,name = _name;
  • @synthesize可以不写,只写@property就可以完成成员变量getter和setter方法的声明和实现

七、description方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main()
{
    //输出行号
    NSLog(@"%d",__LINE__);
 
    //NSLog输出C语言字符串的时候,不能有中文
    NSLog(@"%s",__FILE__);
 
    //输出源文件路径名称
    printf("%s\n",__FILE__);
 
    //输出当前函数名
    NSLog(@"%s",__func__);
 
    return 0;
}
 
void test()
{
    Person *p = [[Person alloc] init];
    p.age = 20;
    p.name = @"Jack";
     
    //1.首先会调用对象的-description方法,返回字符串
    //2.拿到-description方法的返回值,并显示到屏幕上
    //description方法默认返回“类名+内存地址” <Person 0x0232010>
    //所以需要重写description方法
    //相当于java的Object的toString()方法
    NSLog(@"%@",p.description);
 
    Person *p2 = [[Person alloc] init];
    p2.age = 22;
    p2.name = @"Ted";
    NSLog(@"%@",p2.description);
}
 
void test2()
{
    Class c = [Person class];
 
    //1.首先会调用类的+description方法
    //2.拿到+description方法的返回值(NSString *)显示到屏幕上
    NSLog(@"%@",c);
}
 
//重写description方法
- (NSString *)description
{
    //死循环
    //NSLog(@"%@",self);
    
    return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name];
}
 
+ (NSString *)description
{
    return @"sss";
}

八、id类型

  • id是一种类型
  • id是万能指针,能操作任何OC对象,id内部已经包含*,所以不用再加*
  • 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    //id是一种类型
    //id是万能指针,能操作任何OC对象,id内部已经包含*,所以不用再加*
    //id d;
       
    //Person *p = [Person new];
         
    //id == NSObject*
    //NSObject *o = [Person new];
    
    //只适用OC对象
    id person = [Person new];
    [person setAge:10];
    [person setObj:@"luoguankun"];
 
    NSLog(@"age=%d",[person age]);
    test(person);
     
    return 0;
}

九、SEL

  • SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可以调用方法
  • 其实消息就是SEL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int main()
{
    //[Person test];
    Person *p = [[Person alloc] init];  
 
    //1.把test2包装成SEL类型的数据
    //2.根据SEL数据找到对应的方法地址
    //3.根据方法地址调用对应的方法
    //[p test2];
 
    //通过SEL简介调用test方法
    [p performSelector:@selector(test2)];
 
    //上面的调用相当于下面这两步
    //SEL s = @selector(test2);
    //[p performSelector:s];
 
     
 
    //通过SEL带参数的形式调用test3方法,不要忘了带上冒号
    [p performSelector:@selector(test3:andluo:) withObject:@"luo" withObject:@"feng"];
 
    return 0;
}
 
 
 
//字符串转换成SEL
NSString *name = @"test2";
SEL s = NSSelectorFromString(name);
 
 
 
//SEL转换成字符串
- (void)test2
{
    //死循环
    //[self performSelector:_cmd];
     
    //_cmd是SEL类型,代表当前方法
    //通过NSString的fromSelector方法把SEL转换为字符串
    NSString *str = NSStringFromSelector(_cmd);
 
    //打印_cmd
    NSLog(@"%@",str);   //打印test2
}

 

OC语言自学基础知识总结的更多相关文章

  1. Java学习-033-JavaWeb_002 -- 网页标记语言JSP基础知识

    JSP 是 Sun 公司提倡的一门网页技术标准.在 HTML 文件中,加入 Java 代码就构成了 JSP 网页,当 Web 服务器访问 JSP 请求的时候,首先执行其中的 Java 程序源码,然后以 ...

  2. iOS开发系列--C语言之基础知识

    概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...

  3. 3011C语言_基础知识

    第一章  基础知识 1.1  基本框架 //任何一个c语言程序都必须包括以下格式: int main(int argc, char *argv[] ) { : } //这是c语言的基本结构,任何一个程 ...

  4. 【值得收藏】C语言入门基础知识大全!从C语言程序结构到删库跑路!

    01 C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { ...

  5. Oracle的DML语言必备基础知识

      前提是咱们都已经对常用的数据操纵语言非常熟悉了,对标准SQL: SELECT子句                --指定查询结果集的列 DROM子句                 --指定查询来 ...

  6. C语言面试基础知识整理

    一.预处理 1.什么是预编译?何时需要预编译? (1)预编译又称预处理,是做些代码文本的替换工作,即程序执行前的一些预处理工作.主要处理#开头的指令,如拷贝#include包含的文件代码.替换#def ...

  7. 动态样式语言—LESS基础知识

    CSS是一门非程序式语言,缺少逻辑性,不便于维护 LESS在CSS现有语法的基础上,为CSS加入程序式语言的特性 引入了变量.混入.运算.函数等功能,大大简化CSS的编写,降低了CSS的维护成本 LE ...

  8. Tcl语言学习--基础知识

    一.脚本.命令和单词符号 一个TCL脚本可以包含一个或多个命令.命令之间必须用换行符或分号隔开. 1.关键字/变量 变量是程序的基础变量组成:变量名.变量值变量名要求:任何字符串都可以作为变量名,区分 ...

  9. 关于XML(可扩展标记语言)的基础知识与写法------2017-05-18

    XML(Extensible Markup Language) HTML:超文本标记语言,主要用来展示   XML:可扩展标记语言,用来做数据传输XML特点: 1.树状结构,有且只有一个根 2.标签名 ...

随机推荐

  1. python学习(内置函数)

    1.id()返回对象的内存地址 a = 1 print id(a) print id(1) 2.int()用于将数据类型转换为整型 a = " b = 2 print int(a) + b ...

  2. Windows快捷方式绑马

    0x01前言 windows的shell32在处理控制面板程序的快捷方式文件时,存在一个漏洞,可以加载硬盘上的任意DLL文件,即可执行任意代码. 之前看到一款俄罗斯黑阔写的的快捷方式下载木马并运行的生 ...

  3. php 加入 unless 语法

    1. php 的版本 :PHP 7.3.0-dev (cli) (built: Mar 18 2018 00:28:55) ( NTS ) 2. unless 语法结构: unless($cond){ ...

  4. java 线程池那点事儿

    1.为什么要用线程池 2.常见线程池以及参数 2.1 创建线程池 2.2 线程池参数 2.3 常见线程池 3.执行流程 4.健康检查 1.为什么要用线程池 线程池提供了一种任务的提交与任务的执行解偶的 ...

  5. i春秋DMZ大型靶场实验(二)提权漏洞

    拿到靶场 直接进行扫描 爆破路径 发现 phpinfo, phpmyadmin  更具phpinfo 获取跟路径  也可以通过 输入错路径爆出绝对路径 phpmyamin  弱口令登录  root,r ...

  6. ArcGIS Engine空间查询功能的实现(QueryFilterClass+SpatialFilterClass)

    地图中包含大量的信息,为了快速地了解所需信息,必须借助为空间数据专门编写的空间查询功能. 空间查询主要有两种类型: 基于属性的查询,也称为属性查询. 基于空间位置的查询,也称为空间查询. 查询类的基本 ...

  7. Dubbo 在 K8s 下的思考

    作者 | 曹胜利  Apache Dubbo PMC 导读:Dubbo 作为高性能 Java RPC 框架的刻板印象早已深入人心,在 Cloud Native 的架构选型上,Spring Cloud ...

  8. Spring Cloud zuul网关服务 一

    上一篇进行Netflix Zuul 1.0 与 gateway的对比.今天来介绍一下 zuul的搭建及应用 Zuul 工程创建 工程创建 cloud-gateway-zuul.还是基于之前的工程 po ...

  9. 彻底理解Python多线程中的setDaemon与join【配有GIF示意】

    在进行Python多线程编程时, join() 和 setDaemon() 是最常用的方法,下面说说两者的用法和区别. 1.join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B. ...

  10. Leetcode Tags(1)Linked List

    1.知识点回顾 https://www.cnblogs.com/BigJunOba/p/9174206.html https://www.cnblogs.com/BigJunOba/p/9174217 ...