oc 里的匿名对象

oc 这里,很少用到,因为并不适用于oc的内存管理,只是面试笔试也许出现,要求能看懂,不要在项目里这样写,因为写匿名对象,会造成内存泄露

#import <Foundation/Foundation.h>
@interface Car : NSObject
{
@public
int speed;
}
- (void)run;
@end @implementation Car
- (void)run
{
NSLog(@"%d", speed);
}
@end
int main()
{
//所谓匿名对象,就是没有名字的对象,看不到,但是对象确实存在
[Car new]->speed = 300;//没有指针变量指向对象,而是直接调用类的成员变量,因为每次使用[Car new]都会从新创建一个新对象,故不是300,而是默认初始化的值0
[[Car new] run];//0 // Car *c = [Car new];
// c->speed = 100;
// [c run];//100
return 0;
}

能看懂什么意思就行

类的成员变量的命名规范

  • 成员变量都以下划线 _ 开头
  • 可以跟get方法的名称区分开
  • 可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是类的成员变量

OC弱语法

1、OC是动态检测错误,OC里调用一个没有声明也没有实现的对象方法,则不会编译报错而是警告,链接也能通过,只有运行才检测出错

2、Oc里调用只有声明,但是没有实现的对象方法,这编译也是警告,链接通过,运行才出错

3、Oc调用只有实现(没声明)的方法,则没有问题!因为运行时才检测程序的问题,声明其实只是摆设,删掉是没事的。只不过开发中,必须规范!该写都要写上。即使不报错。

类方法

直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)

1.  类方法和对象方法对比

1)   对象方法

  • 减号-开头
  • 只能让对象调用,没有对象,这个方法根本不可能被执行
  • 对象方法能访问实例变量(成员变量)

2)   类方法

  • 加号+开头
  • 只能用类名调用,对象不能调用
  • 类方法中不能访问实例变量(成员变量)
  • 使用场合:当不需要访问成员变量的时候,尽量用类方法

3)       类方法和对象方法可以同名

4)       提高程序性能

类方法的好处和使用场合:不依赖于对象,执行效率高, 能用类方法,尽量用类方法

// 类方法都是以+开头
+ (void)printClassName;
- (void)test;
+ (void)test; //可以允许类方法和对象方法同名

self 关键字用来指明对象是当前方法的接收者。

  • 当成员变量和局部变量同名时,采取就近原则,访问的是局部变量
  • 用self访问成员变量,区分同名的局部变量

细节:

1)    出现的地方:可以出现在所有的OC方法中(对象方法\类方法),但是不能出现在函数里

2)    作用:

使用 "self->成员变量名" 访问当前方法调用的成员变量

使用 "[self 方法名];" 来调用方法(对象方法\类方法)

#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int _age;
}
- (void)setAge:(int)age;
- (int)age;
- (void)test;
@end @implementation Person
- (void)setAge:(int)age
{
// _age = age;相当于
self->_age = age;
}
- (int)age
{
return self->_age;
}
- (void)test
{
// self:指向了方向调用者,代表着当前对象
int _age = ;
NSLog(@"Person的年龄是%d岁", self->_age);
} @end int main()
{
Person *p = [Person new]; [p setAge:]; [p test]; return ;
}
/* self的用途:
1> 谁调用了当前方法,self就代表谁
* self出现在对象方法中,self就代表对象
* self出现在类方法中,self就代表类
2> 在对象方法利用"self->成员变量名"访问当前对象内部的成员变
[self 方法名]可以调用其他对象方法\类方法 */
#import <Foundation/Foundation.h>
@interface Dog : NSObject
- (void)bark;
- (void)run;
@end @implementation Dog
- (void)bark
{
NSLog(@"汪汪汪");
}
- (void)run
{
[self bark];//self代表指针d指向的对象,NSLog(@"汪汪汪");
NSLog(@"跑跑跑");
}
@end int main()
{
Dog *d = [Dog new]; [d run]; return ;
}

低级错误:

用self去调用函数

类方法中用self调用对象方法,对象方法中用self调用类方法

self死循环

#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)test;
+ (void)test; - (void)test1;
+ (void)test2; - (void)haha1;
+ (void)haha2;
@end @implementation Person
- (void)test
{
NSLog(@"调用了-test方法");
// 如果有[self text];这句,就会引发死循环。因为[self test];self代表对象,一直调用对象方法test
}
+ (void)test
{
NSLog(@"调用了+test方法");
// 引发死循环 [self test];self代表类,一直调用类方法test
}
//自动识别
- (void)test1
{
[self test]; // ok,-test
} + (void)test2
{
[self test]; // ok,+test
} - (void)haha1
{
NSLog(@"haha1-----");
}
//函数
void haha3()
{
} + (void)haha2
{
haha3();//ok,一定注意函数和方法是不一样的!
//[self haha3];//error,不能用self调用函数
//[self haha1];//error,类方法里,不能用self调用对象方法,相反,在对象方法里,也不能用self调用类方法
}
@end int main()
{
[Person haha2];//直接调用类方法
//Person *p = [Person new];
//[p test1];
return ;
}

原则上(如果不使用 ARC,也就是自动引用计数),那么

创建一个新对象,都要请求分配内存,在完成对该对象的操作时,必须释放其所用的内存空间。类似 c++的内存管理。

与 C 语言兼容的地方:

预处理:

#define 语句和 c 一样

#运算符: #define str(x) #x

表示在调用该宏时,预处理程序根据宏参数创建C 风格的常量字符串。

例如:str("hello")将产生"\"hello"\"

##运算符:
表示用于把两个标记连在一起

#import 语句;相当于#include 语句,但是 #import 可自动防止同一个文件被导入多次。

#条件编译语句(#ifdef 、#endif 、 #else 、 #ifndef)和 C 一样

#undef 语句 消除特定名称的定义

其他基本的C 语言特性:

数组、函数、指针、结构、联合的用法和C 一样。

Compound Literal 是包含在括号之内的类型名称,之后是一个初始化列表。

例如

如果 intPtr 为 int * 类型:
intPtr = (int[100]){[0] = 1, [50] = 50, [99] = 99};

如果数组大小没有说明,则有初始化列表确定。

其他如循环语句 (do while、while、for) 、条件语句(if 语句(if-else、复合判断条件等) 、switch 语句)、 Boolean(YES NO)、条件运算符、goto 语句、空语句、逗号表达式、sizeof 运算符、命令行参数、位操作都 和 C 一样 。

oc 的继承

oc的继承只支持单一继承,和java类似,也就是儿子只能有一个爸爸,但是

可以通过 Objective-C 的分类和协议特性获取多继承的优点

而c++支持单一和多重继承。

好处:

不改变原来模型的基础上,拓充方法

建立了类与类之间的联系

抽取了公共代码

坏处:

耦合性强

基本上所有类的根类是NSObject类

如图:

animal类拥有NSObject类的new方法,子类dog和cat同时拥有前两层类的所有方法和属性。类似 c++和 java

#import <Foundation/Foundation.h>
/* 1.继承的好处:
1> 抽取重复代码
2> 建立了类之间的关系
3> 子类可以拥有父类中的所有成员变量和方法
2.注意点
1> 基本上所有类的根类是NSObject
*/
/********Animal的声明*******/
@interface Animal : NSObject
{
int _age;
double _weight;
} - (void)setAge:(int)age;
- (int)age; - (void)setWeight:(double)weight;
- (double)weight;
@end
/********Animal的实现*******/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
} - (void)setWeight:(double)weight
{
_weight = weight;
}
- (double)weight
{
return _weight;
}
@end /********Dog*******/
// 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法
// Animal称为Dog的父类,Dog称为Animal的子类
@interface Dog : Animal
@end @implementation Dog
@end /********Cat*******/
@interface Cat : Animal
@end @implementation Cat
@end int main()
{
Dog *d = [Dog new]; [d setAge:]; NSLog(@"age=%d", [d age]);
return ;
}

oc 继承里的细节(类似其他面向对象语言)

父类必须声明在子类的前面

子类和父类不能有相同的成员变量,但是方法可以重写

方法的重写问题:子类重新实现父类中的某个方法,也就是覆盖了父法

调用某个方法时,优先去当前类中找,如果找不到,去父类中找

这是内部原理。

每个对象都有一个isa指针,指向对象属于的类,且记住:每个类里(oc的)都有一个superclass指针,指向自己的父类。

这样通过对象就能找到对象属于的类,也能找到类的父类。而这些指针就在NSSobject类里。

内存结构:

继承的使用场合

1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类

// 继承:xx 是 xxx

// 组合(也叫聚合关系):xxx 拥有 xxx

super关键字

实现重写之后,还可以调用父类的对象方法和类方法,super的作用;直接调用父类中的某个方法

1、super处在对象方法中,那么就会调用父类的对象方法

2、super处在类方法中,那么就会调用父类的类方法

使用场合:

子类重写父类的方法时想保留父类的一些行为。

在oc里,简单的多,调用某方法,先是在所在类就近找,找不到去父类找。太简单了。如果重写了父类方法,那么只能调用子类重写的这个方法了,如果想保留父类原方法定义的功能,可以用super。

oc 的多态

多态的体现

Person *p = [Student new];

p->age = 100;

[p walk];

子类对象赋值给父类指针,父类指针访问对应的子类的继承来的属性和方法

多态的局限性

不能访问子类的特有的属性或方法(可以考虑强制转换)

多态的细节

动态绑定:在运行时根据对象的类型确定动态调用的方法

注意点:

1.没有继承就没有多态

2.代码的体现:父类类型的指针指向子类对象

3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、或者子类对象

4.局限性:父类类型的变量 不能 直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法(类似c++的赋值兼容)

#import <Foundation/Foundation.h>
// 动物
@interface Animal : NSObject
- (void)eat;
@end @implementation Animal
- (void)eat
{
NSLog(@"Animal-吃东西----");
}
@end
// 狗
@interface Dog : Animal
- (void)run;//子类新增的对象方法run
@end @implementation Dog
- (void)run
{
NSLog(@"Dog---跑起来");
}
- (void)eat//重写父类的-eat方法
{
NSLog(@"Dog-吃东西----");
}
@end // 猫
@interface Cat : Animal
@end @implementation Cat
- (void)eat//重写父类的对象方法eat
{
NSLog(@"Cat-吃东西----");
}
@end
// 如果参数中使用的是父类类型指针,可以传入父类or子类对象
void feed(Animal *a)
{
[a eat];
} int main()
{
Animal *aa = [Dog new];//父类指针指向子类的对象
//[aa run];弱语法,只警告!但是在java或者c++里,早就报错了!父类指针不能访问子类特有的方法,虽然弱语法,但不推荐,自己要认为是错的
// 将父类对象aa转为子类 Dog * 类型的变量就ok了,和c++类似
Dog *dd = (Dog *)aa;
[dd run];//ok,访问的是子类的对象方法 run //Dog *d = [Dog new];
//[d run];//ok /* Animal *aa = [Animal new];父类对象的指针aa
feed(aa);可以传入父类对象做参数,调用的父类的eat方法
Dog *dd = [Dog new];子类对象指针dd
feed(dd); 也可以传入子类的对象做参数,调用的子类的eat方法
Cat *cc = [Cat new];
feed(cc);调用子类eat,传入子类对象参数 */ // 多态:父类指针指向子类对象
Animal *a = [Dog new];
// 调用方法时会检测对象的真实形象,动态
[a eat];调用的时子类的eat方法
*/
return ;
}

多态的局限性:

父类类型的变量 不能 直接 调用子类特有的方法。

联系c++

c++是使用了虚函数,(包括纯虚函数和抽象类)对公有继承的子类的方法,重写虚函数,父类指针或者引用指向子类,那么就能调用子类的重写虚函数,指向父类,就是调用父类的虚函数,实现动态联编。

oc里,没有那么复杂,就是直接子类继承父类,那么重写父类某个对象方法,这只需要父类指针指向子类对象,那么就调用子类的重写方法,同样也不能调用子类特有的方法。

由此断定,oc的方法都是虚方法!不用和c++一样用virtual声明!且oc的重写也是多态的一种,oc里所有的方法访问属性都是公有的!而类成员变量默认是保护的。和c++有些区别,c++是默认都是私有的。

再看oc的弱语法!比如把子类对象指针指向父类

Cat *cat = [Animal new];

c++里肯定错误,但oc里没问题,只警告,但这样不好,不推荐。完全没道理。

再看:

NSString *s = [Cat new];

动物怎么了成了字符串对象了?oc里xcode不报错!但是绝对是不对,不规范。还有,同一个层次的类,猫类指针指向狗类对象,调用eat方法,在oc的弱语法下,还是没问题的,调狗的eat。

oc太弱了!但是在c++里直接就报错了。不可以这样写,即使编译器不报错。

多态的好处

用父类对象接收参数,方法或者函数,即可以接受子类对象,也能接受父类对象,节省代码。否则还要分开写多个方法或者函数。

充分体现面向对象的抽象和具体,通过子类重写继承来的父类的虚方法(oc默认都是),通过父类指针指向子类对象,实现动态多态性!不看指针的类型,而是看指针指向的哪个对象类型,就调用哪个子类对象的虚方法。注意子类特有的方法不可以,必须强转。

欢迎关注

dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!

objective-c 语法快速过(3)的更多相关文章

  1. Objective-C基础语法快速入门

    Objective-C基础语法快速入门 2010-11-04 16:32 折酷吧 zheku8 字号:T | T 假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会 ...

  2. jenkins2 pipeline 语法快速参考

    jenkins2 pipeline中常用的语法快速参考. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciand ...

  3. Razor 语法快速参考

    Razor 语法快速参考   本文引自:http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx 语法名称 Raz ...

  4. 第二章 C#语法快速热身

    C#语法快速热身 语法 if(条件表达式){ 代码块 } 语法 if(条件表达式){ 代码块 }else{ 代码块2 } 语法 if(条件表达式1){ 代码块1 if(条件表达式1)){ }else{ ...

  5. Less 语法快速入门

    Less 语法快速入门 Less 是一门 CSS 预处理语言其可以运行在 Node 或浏览器端. 它将传统的 css 样式结构单一的排版顺序进行了优化,让我们可以通过层级嵌套的方式将 css 类名与H ...

  6. objective-c 语法快速过(6)内存管理原理

    内存管理基本原理(最重要) 移动设备的内存极其有限(iphone 4内存512M),每个app所能占用的内存是有限制的(几十兆而已). 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不 ...

  7. objective-c 语法快速过(4)

    oc 里的字符串 字符串的快速创建(最简单的方法) NSStirng *str = @“Hello”;//oc的字符串都是@“”形式的 oc的字符串也是类的对象,是NSString类的对象,创建没有那 ...

  8. objective-c 语法快速过(1)

    有一定 c++或者 java 基础,过一遍 oc 语法即可,都是相通的,个人认为难点是 oc 的内存管理,虽然有了 ARC,但是也需要学习下,因为有旧软件的维护. 建立在C语言的基础上,增加了一层小范 ...

  9. Emmet语法 —— 快速生成HTML结构

    快速生成HTML结构语法 1.生成单个标签 : 标签名+tab,比如 div 然后tab 键, 就可以生成 <div></div> 2.生成多个相同标签 div*3 + tab ...

  10. objective-c 语法快速过(8)

    Block(oc 的数据类型,很常用,本质是c结构体) 类似内联函数,从源代码层看,有函数的结构,而在编译后,却不具备函数的性质.编译时,类似宏替换,使用函数体替换调用处的函数名 Block封装了一段 ...

随机推荐

  1. webstorm2016注册码

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...

  2. QComboBox的activated与currentIndexChanged的区别

    void activated ( int index ) void activated ( const QString & text ) 信号activated是只要单击选择框即使所选内容选择 ...

  3. Grunt 使用记录

    想了解Grunt,可以先去官网 看看. 第一次接触Grunt是通过Coding的移动端项目, 刚开始因为环境的问题折腾了一两天,然后就顿悟了. Grunt构建工具对于前端开发而言,简直是神器(ps.虽 ...

  4. jquery mobile 问问多多

    jquery mobile  问题多多,兼容性太差.android4.1下完全崩溃.以后再也不用jquery mobile了

  5. Allegro之Enhance pad Entry(增强焊盘进入约束功能)的使用

    pcb布线时,有时候会从器件的焊盘往外拉线,为了避免出现类似情况 出现锐角焊盘内绕线等等 可在add connect操作下,右键勾选Enhance pad Entry来增强焊盘进入的约束,可有效防止上 ...

  6. C#中常用的读取xml的几种方法(转)

    本文完全来源于http://blog.csdn.net/tiemufeng1122/article/details/6723764,仅作个人学习之用. XML文件是一种常用的文件格式,例如WinFor ...

  7. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  8. Maven和Gradle对比

    Java世界中主要有三大构建工具:Ant.Maven和Gradle.经过几年的发展,Ant几乎销声匿迹.Maven也日薄西山,而Gradle的发展则如日中天.笔者有幸见证了Maven的没落和Gradl ...

  9. 【原】Python用例:将指定文件或目录打包成zip文件

    #This Demo is used to compress files to .zip file #Base on Windows import os import time #The files ...

  10. spring官网下载

    1.第一步:打开官网:http://projects.spring.io/ 2.第二步:点击“SPRING FRAMEWORK”图片 3.第三步:点击“小猫”图标 4.第四步:拉到页面中部的位置,找到 ...