IOS学习笔记之Object-C(一)

++ 概述 ++
目前来说,Objective-C(简称OC)是iOS开发的核心语言,在开发过程中也会配合着使用C语言、C++,OC主要负责UI界面,C语言、C++可用于图形处理。

  • 基于C语言:C语言是一门面向过程的语言,OC是在C语言的基础上,增加了一层最小的面向对象语法,为什么说是最小的面向对象语法呢?因为OC把一些比较复杂的面向对象语法都去掉了,剩下的都是面向对象的精华,因此OC是一门面向对象的语言,而且会比C++简单很多。因为OC是基于C语言的,所以完全兼容C语言,也就是说我们在开发iOS程序过程中,可以在OC代码中混入C语言代码,甚至是C++代码。

语法概述:
1.没有包名(命名空间)的概念


在Java中,为了防止两个类名相同的类冲突,你可以将这2个类放在不同的包里面。OC中并没有”包"的概念,也就是没有命名空间机制,取而代之的是开发人员给类名加上前缀,使用前缀可以有效的防止类名冲突。比如NSString(OC中的字符串类)、NSArray(OC的数组类),它们的前缀都是NS
2.关键字都以@开头
OC代码中是可以混入C语言、C++代码的,而C语言和C++作为一门编程语言,都有自己的关键字。为了防止跟C语言、C++关键字冲突,OC的关键字都以@开头。
甚至字符串都是以@开头的,比如@“Hello"是OC中的字符串,而"Hello"则是C语言中的字符串。
语法要点:

语法要点

Oc没有垃圾回收;
源文件后缀为.m;入口程序同c,也是main()
导包使用 #import 也不用使用条件编译加入头文件;#import会自动判断是否已经添加过该头文件。

+面向对象语法

一般用2个文件来描述一个类;
.h:类的声明文件,用于声明成员变量、方法。类的声明使用关键字@interface@end
[注意:.h中的方法只是做一个声明,并不对方法进行实现。也就是说,只是说明一下方法名、方法的返回值类型、方法接收的参数类型而已,并不会编写方法内部的代码。]
.m:类的实现文件,用于实现.h中声明的方法。类的实现使用关键字@implementation@end
.h

//用于声明Student这个类由哪些成员变量和方法(面对对象称方法,面向过程称函数)
//导包,Foundation包含了常用的类,(类似java中的java.lang类)
#import <Foundation/Foundation.h>
//@interface表示声明一个类,后是类名;必须要指定继承的父类(java中是自动继承object)
// : 即是继承
//@end表示一个类的结束
@interface Student : NSObject{
    //成员变量要定义在大括号中;
    int age;
    int no;
}
//OC在.h中声明的方法都是公用方法
//Oc中凡是方法类型都用括号括起来(int)
//成员变量age的get方法
// - 代表动态方法,就是对象内部方法;+ 代表静态方法
- (int)getAge;//OC中不建议使用get*写法,建议直接与变量名一样
-(int)age;
//age的set方法;一个冒号对应一个参数
- (void)setAge:(int)newAge;
//同时设置两个参数的set方法
-(void)setAge:(int)newAge andNo:(int)newNo;
-(int)no;
@end

使用:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建对象
        //1.调用一个静态方法alloc来分配内存
        //2.创建一个该对象的指针指向刚创建的内存空间
        Student *stu = [Student alloc];
        //3.调用一个动态方法进行初始化;
        //相当于调用了Student对象的init方法;
        stu = [stu init];
        [stu setAge:100];
        [stu getAge];
        [stu age];
        //上面三步可合并为
        Student *stu1 = [[Student alloc] init];
        [stu1 setAge:10 andNo:101];
        NSLog(@"age :%d,no %d:",[stu1 age],[stu1 no]);
        //释放对象,但若选择了ARC编译器会自动添加
        [stu release];
    }
    return 0;
}

++ 点语法 ++
为了方便其他程序员熟悉而做的处理;其本质还是方法调用

Person *person = [[Person alloc] init];
     //点语法,为了方便其他程序员熟悉而做的处理
     //    [person setAge:10];
    // 注意:不是访问成员变量;为了防止混淆,OC规范成员变量以_开头
    person.age = 10;//等效于[person setAge:10];(
    //    int age = [person age];
    int age = person.age;//等效于 int age = [person age];

方法名:

//方法也是方法名的一部分;故该方法的方法名是setAge:
-(void)setAge:(int)newAge;
//故该方法的方法名是setAge:andNo:
//-(void)setAge:(int)newAge andNo:(int)newNo;
//方法名是age;
-(int)age;

注意:

@implementation Person
-(void)setAge:(int)newAge{
    _age = newAge;
    //方法相当于[self setAge:newAge],即又调用了自身,则会无限循环调用自己
//    self.age = newAge;
}
-(int)age{
    //相当于[self age],也会调用自身,会无限调用自己
//    return self.age;
    return _age;
}
@end

stu->age;是直接访问成员变量,但只能访问@public修饰的变量;

stu.age=18;是调用setAge方法。
++ 构造方法 ++
.h中

//自定义一个构造方法,是一个动态方法,内部方法
//由于系统的构造方法返回都是id,为保持一致,也返回id;(id可代表所有OC对象指针)
-(id)initWithSize:(int)size andPrice:(double)price;

.m中

//实现构造方法
-(id)initWithSize:(int)size andPrice:(double)price{
    //首先要调用父类的实现方法
    //    self= [super init];
    //再进行赋值
    //父类返回的对象可能会为空
    //相当于if (self!=nil)
    //    if (self){
    //        _size = size; //或 self._size = size;
    //        _price = price;
    //    }
    //或者上面的可简化为
    if (self = [super init]) {
        _size = size;
        _price = price;
    }
    return self;
}
//重写,类似于java中对象的toString
//...同java,代表多个参数
//NSString *str = @"str";是OC中的字符串,为区别C,都加 @;
- (NSString *)description
{
    return [NSString stringWithFormat:@"size:%i,price:%f", _size,_price];
}

%@表示打印一个OC对象,需重写(NSString *)description方法(同java的toString);
NSLog(@" to string %@“,car);

...同java,代表多个参数
[所有返回*的地方都可以用id代替,且id是关键字,不能直接做变量名]

变量的使用域:
类的成员变量默认是protected的,一般使用默认的即可,不需要添加修饰符
**@public **:全局都可访问,成员变量可用->直接访问;
@protected:只能在类内部和子类访问
@private :只能在类内部访问
(OC中没有包的的概念,故没有default)
- 代表动态方法,就是对象内部方法;
+ 代表静态方法
[静态方法同java,也可使用self,但不同的是在静态方法中的self意思是指向的类名,而不是self对象]
(即 谁调用方法,self就指向谁)
静态方法不能访问成员变量;
在头文件中声明的方法都是public的;
若直接写在.m文件中的方法,没有在.h文件中进行声明,那么这个方法是私有方法

+内存释放
系统自带的静态方法创建的对象都会自动释放;
1.在定义时自动释放:
Car *car = [[[Car alloc] initWithSize:10 andPrice:23.0f] autorelease];
2.手动释放
[person release];
autorelease 是在适当的时机释放,而不是马上释放.
+**new **
Student *stu= [Student new];//相当于Student *stu = [[Student alloc] init]
但很少用new,这是新版本才添加的关键字;

@property 生成set/get的声明
为了解决set/get方法的冗余的麻烦;
只用在.h文件里,用于声明方法(set/get)
@property int age;//编译器遇到@property时,会生动生成set/get方法的声明

++ @synthesize++ 生成set/get的实现[同@property是编译器的特性]
为了解决set/get的实现
@synthesize age,no,height;//相当于三个成员变量的实现
[若用synthesize了,即可在.h文件中不写成员变量age,no,height,会默认去访问与age同名的变量,若找不到同名的变量,会自动生成一个同名变量,并且若自己定义的成员变量的名字与@synthesize不一样时,会默认创建自动生成的]
[但为了统一风格,成员变量以
开头,需要指定@synthesize默认生成的变量名,如:@synthesize age=_age,no=_no,height=_height;]

故在定义类的成员变量时,一般需声明变量名;直接在头文件使用@property,.m文件中使用@synthesize;
[Xcode在4.5后添加了新特性:.m文件中的@synthesize都可省略(会自动生成@synthesize age=_age,no=_no,height=_height;这句代码,默认自带下划线),也就是直接在.h文件中用@property声明即可]
[但自己写的set/get会优先使用;若自己手动实现了get/set方法,Xcode就不会自成生成@synthesize,也不会生成set/get方法]

+内存管理
管理范围:任何继承了NSObject的对象,对基本的数据类型不需要;
原理:每个对象内部都保存了一个与之有关的整数,称为引用计数器;每当使用alloc,new,copy创建一个对象时,对象的引用计数器被设置为1;给对象发送一条retain消息,可以引用计数器值+1;给对象发送一条release消息,可使引用计数器值-1;当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收,OC也会自动向对象发送一条dealloc消息.一般会重写dealloc方法,在这里释放相关资源.[但一定不要直接调用dealloc方法,是系统自动调用该方法]
— 可用retainCount消息获得当前对象的引用计数器值;
[java中new了一个对象后若没有变量引用,则会自己销毁;但在OC中,若新建了一个对象,没有变量引用,计数器值会为1,若没有手动回收或关闭app,则永不会被回收,]

- (void)dealloc
{
    NSLog(@"系统调用回收方法");
    //一定要调用super的dealloc方法,而且最好放在最后面调用
    [super dealloc];
}

[stu release];方法只能调用一次,若调用多次,会发生野指针错误(访问了不属于你的内存)

“谁创建,谁释放”;若用alloc,new,copy的创建的对象,就必须调用release或autorelease来释放;不是你创建的,就不用你去释放;
“谁retain,谁release”只要调用retain,无论这个对象是谁创建的,都需要release释放;

ARC特性(auto reference count):4.5后的新特性,由编译器自动进行内存释放;

+对象之间的内存管理
//直接调用set的一个对象,对象没有被回收,会造成内存泄露
[stu setBook:[[Book alloc] initWithID:100]];
对象的set方法也会创建一个对象,对象的计数+1;需要对原对象释放;

-(void)setBook:(Book *)book{
 
if(_book != book){//传进来的变量可能已经释放,为了正确,需判断是否为同一个,不是同一个才进行释放和引用;也能保证在多次调用时引用的计数器值不会增加,不会出现内存泄露的情况;
   [_book relase];//先释放旧的成员变量,且不用担心空指针;
   _book = [book retain];//再retain传进来的对象
}
}
[//可在头文件中用 @property (retain )Book *book;代替上面的set方法 ]

[**OC中若对象为nil,调用其方法不能出现空指针异常]
[stu release];/若stu已经释放过了再释放,是野指针会出错
[nil release];//是空指针,再释放,不会报错;
//野指针;在内存中指针仍保留原地址,但现在该块内存的内容已不在原来的内容,也不于属于原内容,故会报错;为避免报错,需要清空原指针(相当于java中的置null)
stu = nil;//清空指针中的地址;
++ 若类中有成员变量是自定义的对象,要先释放:

- (void)dealloc
{
    NSLog(@"系统调用回收方法");
    //一定要调用super的dealloc方法,而且最好放在最后面调用
  //成员变量要释放
    [_book release];
//    NSLog(@"内部对象book计数值:%i",[_book retasinCount]);
    [super dealloc];
}

++ 通常引用一个类的两种方法:#import;@class;
++ @class ++用于声明一个类,不知道实现,在使用时才用#import
**若在.h文件中只是要用到某个类,如定义一个成员变量,没必要用#import “Book.h”;这样是把.h文件的内容拷贝到此处,影响性能(若有上百个类用#import一个类A,A中使用一点改动,则所有子类都会重新编译;而@class则不会);
若只是声明一个成员变量,只用使用@class Book;即可,声明Book这个类即可,提高效率;
[对自定义的对象相互持有的情况下必须用 @class;如A中有B,B中有A;就不能使用#import,会造成递归导入;编译错误]
[对于继承的父类,不能使用@class,须使用#import,用于将父类的头文件拷贝到此处,让子类知道哪些方法已经定义过。]
但在.m要用到这个类下的方法,还是需要#import “Book.h”

+@property 内存管理
@(参数1,参数2)类型 名字;
参数分类:
读写属性:readwrite/readonly;//默认是readwrite,并生成set/get;readonly代表只生成get方法
setter属性:assign/retain/copy;//默认是assign,直接赋值;retain,引用+1;
原子性:atomic/nonatomic;//默认atomic,加锁,提供了多线程安全;nonatomic,禁止多线程,变量保护,可提高性能;[对于在iPone这个小型设备上,内存很小,默认情况下不需要考虑太多的多线程,以提高性能]
(在做IOS开发时,尽量多使用nonatomic)
如:

@property (nonatomic,assign) int ID;
@property (nonatomic,retain) Book *book;
@property (nonatomic,getter=isEnable) BOOL enable;//指定get的方法名;
@property (retain)Card *card;//就相当于上面手动判断,释放再retain的set方法;(若是基础类型不需要添加,否则要添加retain)

+autorelease pool自动释放池
OC中的一种内存自己回收机制,一般可将一些临时变量添加到自动释放池中,统一回收释放;
当自动释放池销毁时,池里面的所有对象都会调用一次release方法;
使用:OC对象只需要发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池);autorelese实际上是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了autorelease pool中,当pool被释放时,该pool会调用一次所有的对象relase方法。
[若使用autorelease 后就不需手动释放]
[autorelease pool会在程序执行完成后销毁]

//代表创建一个自动释放池;
    @autoreleasepool {
        //        testMemoeryReales();
        Student *stu = [[Student alloc] init];
        //只是把对象放到autorelease pool中;当autoreleasepool被销毁时,会自动调用一次池里所有的对象的release方法,
        [stu autorelease];
        //则上面可简化成
        Student *stu1= [[[Student alloc] init] autorelease];
    }

*[IOS5.0之前: NSAutoreleasePool *pool = [[NSAutorelease] alloc]init]; [pool release];(在ARC下,不能使用这种方法,只能使用@autoreleasepool;ARC本质上就是一个释放池的操作)]

[NOTE:不要在一个autoreleasepool中放入大量循环操作(for,while等,应使用手动release);尽量以免对大内存使用方法,对于这种延迟释放机制,尽少使用;SDK中一般利用静态方法创建并返回的对象都是已经autorelease的,不需要再release操作;]
自定义一个快速创建的构造方法:

+(id)student{
    return [[[Student alloc] init] autorelease];
}

[规范:静态方法返回的对象都是自己负责释放的]

感谢李明杰老师@M了个J的讲解及时详细的课件(http://www.cnblogs.com/mjios)

博客地址:IOS学习笔记之Object-C(一)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Objective-C 1. import的用法 拷贝文件内容可以自动防止文件的内容被重复拷贝(#define宏定...
    马文涛阅读 5,326评论 3 17
  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 827评论 0 4
  • 1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch...
    阳光的大男孩儿阅读 4,967评论 0 13
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,944评论 1 16
  • 他们潮湿了 他们无能为力 他们燃烧不起来 天空潮湿了 太阳无能为力 太阳燃烧不起来 而地面 自然主宰着——请注意 ...
    文森林木阅读 94评论 0 0