Objective-C 30分钟入门教程
2015-10-02 11:14
489 查看
Objective-C 30分钟入门教程
我第一次看OC觉得这个语言的语法有些怪异,为什么充满了@符号,[]符号,函数调用没有()这个,但是面向对象的高级语言也不外乎类,接口,多态,封装,继承等概念。下面会把OC里面的一些定义与Java,C++作对比,让有其他面向对象语言的同学可以快速的了解OC是个神马语言。1.类定义
类用@interface定义,而不是@class,相当于Java中的class了。而Object-C中接口(Java中的接口)是用@protocol(下面有介绍)表示。头文件,与c++的头文件类似
#import <Foundation/Foundation.h> @interface Fraction : NSObject //成员变量 { @protected int numerator; int denominator; } //类方法 -(void) print; //多参数函数 -(id)initSetNum:(int) n over:(int) d; -(id) init; @end
实现.m文件(相当于c中的.cpp)
#import "Fraction.h" @implementation Fraction -(void) print { NSLog(@"print"); } -(id)init{ self = [super init]; if (self != nil) { self->denominator = 1; self->numerator = 1; } return self; } -(void)set:(int)n over:(int)d { self->denominator = d; self->numerator = n; } @end
init模板
-(id)init{ self = [super init]; if (self) { //do init } return self; }
2.访问权限
实例变量的作用域
@protected: 实例变量可被该类和子类中定义的方法直接访问。接口部分定义的实例变量是此作用域@private: 只能被定义在此类中的方法直接访问。定义在实现部分的实例变量默认为此作用域
@public: 可被此类中的方法、子类或其他类直接方法(访问方法见下面点语法)
@package: 对于64位镜像,可以在实现改类的镜像中的任何地方访问此实例变量(不了解,没用过)
@property作用域
@property只在@interface中使用,是默认的@protected权限方法的作用域
@protected,@private,@public,@package不适用实例方法,在@interface中定义的方法都是@public方法
私有方法
1.不在@interface中声明,直接写到@implemention里。2.写在[b]空分类中。[/b]
3.@property和@synthesize
语法@property(attribute1, attribute2, ...) type name;
作用1:生成成员变量的get和set方法
@interface Fraction : NSObject @property int numerator, denominator; -(void)print; @end
@implementation Fraction @synthesize numerator = _abc, denominator = _def; -(void) print { self->_abc = 12; self->_def = 30; } @end
#import <Foundation/Foundation.h> #import "Fraction.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... Fraction * fraction = [[Fraction alloc]init]; [fraction setNumerator:10]; NSLog(@"numerator is %d", [fraction numerator]); fraction.numerator = 20; NSLog(@"numerator is %d", fraction.numerator); } return 0; }
@property int numerator, denominator;
@synthesize numerator = _abc, denominator = _def;
两句话为我们生成了(暂时不考虑内存管理)
(void) setNumerator:(int) n { //@synthesize numerator, denominator; 若是这样则 //self->numerator = n; self->_abc = n; } (void) setDenominator:(int) n { self->_def = n; } (int) numerator { return self->_abc; } (int) denominator { return self->_abc; }
如果不写@synthesize,编译器会自动生成@ synthesize name = _name
若写@synthesize name,则相当于写了@synthesize name = name
点语法
oc的点语法比较特殊,c++或java定义一个实例变量,则可以this->num或instance.num就可以取得次变量了,但是oc不行!点相当于调用set和get方法,并且oc中的实例方法调用也不能用点(get set不算),比如instance.print()是不行的,要[instance print]才行
作用2:协助内存管理
attribute主要分三类:
读写属性:(readwrite/readonly)决定是否生成set访问器,默认为readwrite
setter语义:(assign/retain/copy/strong/weak/unsafe_unretained)set访问器的语义,决定已何种方式对数据成员赋予新值,默认为assign
原子性:(atomic/nonatomic)是否是原子性访问,默认为nonatomic
readwrite: 生成setter/gettter方法(默认)
readonly: 只生成getter。@synthesize不会生成setter方法,所以不能和copy/retain/assign同时使用
assign: 简单赋值,不更改索引计数
retain: 释放旧的对象,将旧对象的值赋予输入对象,在增加输入对象的引用计数(+1)。此属性只能用于Objective-c对象类型,不能用于基本类型和Core Foundation对象(Core Foundation?此乃何物),因为他们没有引用计数
strong/weak/unsafe_unretained: xcode5加入的新属性,strong = retain,unsafe_unretained = assign,weak ~= assign,在引用计数为0时,对吧对象赋值为nil
copy: 建立一个引用计数为1的对象,然后释放旧对象。此属性只对实现了NSCopying的对象类型有效
atomic/nonatomic: setter和getter是不是原子操作,如果是atomic则在多线程情况下,setter和getter中不会被阻塞(切换线程)
4.分类(category)和协议(protocol)
分类
这个概念在c++和java我找不到对应的概念,算是oc特性了在一个类已经定义好了的情况下,又想向类中增加一些新方法,但是有不想改原来的实现文件,或是找不到实现文件,这就是分类发挥作用的时候了,比如想在Fraction类中增加-(void)double方法,用分类可以这么搞
MathOps.h文件
#import "Fraction.h" @interface Fraction(MathOps) -(void)double; @end
MathOps.m文件
#import "Fraction.h" @implementation Fraction(MathOps) -(void)double { [self numerator] = [self numerator] * 2; } @end
这样就可以在Fraction的实例上使用[fraction double];了
类实例变量的扩展
类实例的扩展智能在未命名分类中定义,在命名分类中是不允许的#import "Fraction.h" @interface Fraction() //括号里是空就是了 { int MaxNum; } @property int minNum; @end
Objective-C第229页说,未命名分类是非常有用的,因为他们的方法都是私有的,如果要谢一个类,而且数据和方法仅供这个类本身使用,未命名分类比较合适,可是我试了,外部也能访问啊?
协议@protocol
协议有点像java中的接口,只提供方法的声明,实现由使用此协议的类来实现@protocol NSCopying -(id)copyWithZone:(NSZone *)zone; @end
采用协议的类用<protocolName1,protocolName,...>来声明采用了protocolName协议
@interface className: NSObject
协议中的方法类中不用全部实现,@optional后的方法不一定要实现,@required或默认的方法一定要实现
@protocol Drawing -(void)paint; //采用的类中必须实现 -(void)erase; //采用的类中必须实现 @optional -(void)outline; //采用的类中不一定实现 @required -(void)showDetail; //采用的类中必须实现 @end
可以在声明对象时候指明它采用的协议,这样在赋值时由编译器检查被复制对象是否采用了协议,若没有则发出警告
id<Drawing> currentOBject;
协议自身也可以扩展其他的协议 @protocol Drawing3D
分类也可以采用协议 @interface Fraction(Stuff)
5.Foundation框架
Foundation框架,Application Kit框架,Cocoa框架是由许多类、方法、函数和文档按照一定的逻辑组合起来的集合,在Mac OS X系统下大约有90多个框架。
为所有的程序开发奠定基础的框架称为Foundation框架,它允许使用一些结拜的对象,如数字和字符串,一些对象集合,如数字、字典和集合。其他功能包括处理日期和时间、自动化的内存管理、文件系统等。
Application Kit框架包含广泛的类和方法,它们用来开发交互式的图形应用程序,使得开发文本、菜单、工具栏、表、窗口之类的过程变得十分简便(Application Kit开发Mac app,UIKit开发手持IOS ap)。术语Cocoa Touch是指Foundation、Core Data和UIKit框架。术语Cocoa是指Foundation、Core Data、Application Kit框架。
NSNumber: 把int、float、char等基本类型搞成对象,以便可以放到NSArray等必须存储对象的容器。
NSString/NSMutableString: 字符串类,一个不可变,一个可变
NSArray/NSMutableArray: 数组类,一个不可变,一个可变
NSArray * name = [NSArray arrayWithObjects:@"zhangsan", @"lisi", @"dawang", nil]; NSMutableArray * nameMutable = [NSMutableArray array]; for (int i = 0; i < 10; i++) { nameMutable = [NSNumber numberWithInteger: i]; }
NSValue: 把Foundation集合中的非对象(int、float等用NSNumber)比如C中结构体CGPoint包装(wrapping)成对象,使用时再把对象展开(unwrapping)得到CGPoint。
CGPonit myPonit; NSValue * ponitObj; NSMutableArray * touchPoints = [NSMutableArray array]; myPonit.x = 100; myPoint.y = 200; pointObj = [NSValue valueWithPoint:myPint]; [touchPoints addObject: pointObj]; myPoint = [[touchPoints lastObject]pointValue];
NSDictionary/NSMutableDictionary: 字典,keyValue结构
NSMutableDictionary * glossary = [NSMutableDictionary dictionary]; [glossary setObject:@"zhangSan" forKey:@"zhang"]; [glossary setObject:@"zhaoSi" forKey:@"zhao"]; NSLog(@"name zhang is: %@", [glossary objectForKey:@"zhang"]); NSDictionary * glossaryDic = [NSDictionary dictionaryWithObjectsAndKeys: @"zhangSan", @"zhang", @"zhaoSi", @"zhao", nil]; for (NSString * key in glossaryDic) { NSLog(@"%@:%@", key, [glossary objectForKey: key]); }
NSSet/NSMutableSet/NSIndexSet: 集合类,可用的操作包括搜索、添加、删除、比较、计算交集、计算并集等操作。
6.ARC内存管理
ARC(Automatic Reference Counting)自动引用计数(神马是引用计数自行脑补)。Xcode 4.2版本之后加入的新特性。Xcode4.2之前的内存管理要内存要小心的处理引用计数,retain,release,autorelease在代码中随处可见。XCode4.2之后的ARC是在编译的时候由编译器在代码中添加retain,release,autorelease代码,程序要要做的就是开启ARC(默认开启)功能,在@property属性参数中声明号strong,weak等属性就行了(定义变量时也可以用strong,weak等)。开启ARC后不能使用retain,release,编译不通过。
@autorealeasepool
任何在@autoreleasepool{}中定义的变量都是autorelease的,在出@autoreleasepool{}作用域时,会对其中的变量做一次release操作。Cocoa和IOS应用程序中也有这个@autoreleasepool{},也就是说Cocoa和IOS中的变量都是autorelease的,每帧循环后会对autoreleasepool中的对象做一次pop操作,把对象从autoreleasepool中删除,并做一次release。Objective-C Autorelease Pool 的实现原理这个介绍了ios中的autorealeasepool
7.杂项
NSLog(@"%@", object)
NSLog添加了%@这么一个输出格式,%@对应的对象在编译后会被替换为对descriptionWithLocal方法的调用,如果此方法不存在,则替换为description方法的调用 。//发现需要的再加
结语
本博介绍了OC的核(pi)心(mao)概念,希望看完本博可以对让你对OC有一个大体的认识,学OC是学ios的第一步, 打下坚实的OC还是很必要的。参考
Objective-c的@property 详解Objective-C入门教程03:属性(@property和@synthesize)
OC点语法和变量作用域
Objective-C程序设计(电子书自行百度)
相关文章推荐
- Objective-C字符串操作
- 【IOS 开发学习总结-OC-28】★objective-c之foundation 框架——集合类的综述
- Django操作model时刻,一个错误:AttributeError:’ProgrammingError’ object has no attribute ‘__traceback__’
- Object-C学习笔记之基础知识一
- Object-C学习笔记之基础知识一
- 【IOS 开发学习总结-OC-27】★★objective-c之foundation 框架——对象复制
- Help library 安装arcobjects for .NET异常问题
- 浅析JavaScript引用类型之--Object、Array
- JAVA基础--db11_java异常_Object类
- Objective-C中一种消息处理方法performSelector: withObject:
- Objective-C的initialize和init
- 黑马程序员—UNIX基本指令及第一个Objective-C程序
- [摘要]Effective Objective-C 2.0(三 )
- 关于c#代码Convert.ToChar(null);出现异常,而object obj = null; Convert.ToChar(obj);//返回'\0'空字符问题详解
- web前端-js通过object创建对象
- 【IOS 开发学习总结-OC-26】★★★objective-c——foundation 框架之日期与时间
- JSONobject的使用方法
- 【IOS 开发学习总结-OC-25】★★★objective-c——foundation 框架之字符串
- [解析]Objective-C 深浅拷贝
- 程序运行原理