objective-c
Objective-C与C语言的关系
Objective-C是C语言的严格超集,完全兼容C,C语言编写的程序可以不经修改直接被Objective-C编译。
Objective-C的文件扩展名
扩展名 | 内容类型 |
.h | 头文件。可以包含类,类型,函数和常数的声明 |
.m | 源文件。可以同时包含Objective-C和C代码 |
.mm | 源文件。可以同时包含Objective-C、C代码、C++代码 |
用来包含头文件的编译选项#include,在OC中则建议使用#import,和#include的区别是,#import可以确保相同的文件只会被包含一次。
方法调用格式:
[obj method:argument]
逐个解释:
obj是类的实现对象;
method是要调用的方法;
argument是方法参数;
方法调用必须用[]括起来。
消息传递
OC语言,消息传递模型,对象之间互相传递消息。
C++类别和方法严格清楚,一个方法必定属于一个类别,编译时已经绑定关系,不可能调用一个不存在类里面的方法。
OC类别和消息(方法)的关系松散,调用方法视为对对象发送消息,所有方法都被视为对消息的回应。所有消息处理直到运行时才会动态绑定,并交由类别自行决定如何处理收到的消息。一个类别不保证一定会回应收到的消息,如果类别收到了一个无法处理的消息,程序只会抛出异常,不会出错或崩溃。
[car fly];
发一个fly的信息给car,fly是消息,而car是消息的接收者。car收到消息后会决定如何回应这个消息,若car类别内定义有fly方法就运行方法内之代码,若car内不存在fly方法,则程序依旧可以通过编译,运行期则抛出异常。
字符串
OC语言中使用一个字符串类型来接受字符串,NSString
NSString* myString = @"My String\n";
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];
// 从一个C语言字符串创建Objective-C字符串
NSString* fromCString = [NSString stringWithCString:"A C string"
encoding:NSASCIIStringEncoding];
类
下图展现了声明一个叫做 MyClass 的类的语法,这个类继承自 NSObject 基础类。类声明总是由 @interface 编译选项开始,由 @end 编译选项结束。类名之后的(用冒号分隔的)是父类的名字。类的实例(或者成员)变量声明在被大括号包含的代码块中。实例变量块后面就是类声明的方法的列表。每个实例变量和方法声明都以分号结尾。
类的定义文件遵循C语言之惯例以.h为后缀,实现文件以.m为后缀。
图片来自www.runoob.com
Interface
@interface MyObject : NSObject {
int memberVar1; // 实体变量
id memberVar2;
}
+(return_type) class_method; // 类方法
-(return_type) instance_method1; // 实例方法
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
方法前面的 +/- 号代表函数的类型:加号(+)代表类方法(class method),不需要实例就可以调用,与C++ 的静态函数(static member function)相似。减号(-)即是一般的实例方法(instance method)。
Objective-C定义一个新的方法时,名称内的冒号(:)代表参数传递,不同于C语言以数学函数的括号来传递参数。Objective-C方法使得参数可以夹杂于名称中间,不必全部附缀于方法名称的尾端,可以提高程序可读性(感觉很不习惯( ⊙ o ⊙ )啊!)。设定颜色RGB值的方法为例:
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 宣告方法*/
[myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 呼叫方法*/
这个方法的签名是setColorToRed:Green:Blue:。每个冒号后面都带着一个float类别的参数,分别代表红,绿,蓝三色。
Implementation
@Implementation用于定义类的实现,以@end结尾。
@Implementation内定义的变量是私有的。
创建对象
MyObject * my = [[MyObject alloc] init];
在Objective-C 2.0里,若创建对象不需要参数,则可直接使用new
MyObject * my = [MyObject new];
alloc分配内存,init是初始化对象。
方法
方法声明语法
类方法使用+
实例方法使用-
给myArray变量传递消息insertObject:atIndex:消息
[myArray insertObject:anObj atIndex:0];
一个嵌套的消息
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
下面的例子演示了一个类方法如何作为类的工厂方法。在这里,arrayWithCapacity是NSMutableArray类的类方法,为类的新实例分配内容并初始化,然后返回给你。
NSMutableArray* myArray = nil; // nil 基本上等同于 NULL
// 创建一个新的数组,并把它赋值给 myArray 变量
myArray = [NSMutableArray arrayWithCapacity:0];
属性
属性声明应该放在类接口的方法声明那里。基本的定义使用@property编译选项,紧跟着类型信息和属性的名字。你还可以用定制选项对属性进行配置,这决定了存取方法的行为。下面的例子展示了一些简单的属性声明:
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
属性的访问方法由@synthesize关键字来实现,它由属性的声明自动的产生一对访问方法。另外,也可以选择使用@dynamic关键字表明访问方法会由程序员手工提供。
@implementation Person
@synthesize name;
@dynamic age;
-(id)initWithAge:(int)initAge
{
age = initAge; // 注意:直接赋给成员变量,而非属性
return self;
}
-(int)age
{
return 29; // 注意:并非返回真正的年龄
}
@end
属性可以利用传统的消息表达式、点表达式或"valueForKey:"/"setValue:forKey:"方法对来访问。
Person *aPerson = [[Person alloc] initWithAge: 53];
aPerson.name = @"Steve"; // 注意:点表达式,等于[aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@), property name(%@) and direct instance variable access (%@)",
[aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);
为了利用点表达式来访问实例的属性,需要使用"self"关键字:
-(void) introduceMyselfWithProperties:(BOOL)useGetter
{
NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name)); // NOTE: getter vs. ivar access
}
类或协议的属性可以被动态的读取。(不明白)
int i;
int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList([aPerson class], &propertyCount);
for ( i=0; i < propertyCount; i++ ) {
objc_property_t *thisProperty = propertyList + i;
const char* propertyName = property_getName(*thisProperty);
NSLog(@"Person has a property: '%s'", propertyName);
}
快速枚举
比起利用NSEnumerator对象或在集合中依次枚举,Objective-C 2.0提供了快速枚举的语法。在Objective-C 2.0中,以下循环的功能是相等的,但性能特性不同。
// 使用NSEnumerator
NSEnumerator *enumerator = [thePeople objectEnumerator];
Person *p;
while ( (p = [enumerator nextObject]) != nil ) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// 使用依次枚举
for ( int i = 0; i < [thePeople count]; i++ ) {
Person *p = [thePeople objectAtIndex:i];
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
// 使用快速枚举
for (Person *p in thePeople) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}
快速枚举可以比标准枚举产生更有效的代码,由于枚举所调用的方法被使用NSFastEnumeration协议提供的指针算术运算所代替了。
协议
正式协议类似于Java中的"接口",它是一系列方法的列表,任何类都可以声明自身实现了某个协议。在Objective-C 2.0之前,一个类必须实现它声明匹配的协议中的所有方法,否则编译器会报告错误,表明这个类没有实现它声明匹配的协议中的全部方法。Objective-C 2.0版本允许标记协议中某些方法为可选的(Optional),这样编译器就不会强制实现这些可选的方法。
协议经常应用于Cocoa中的委托及事件触发。例如文本框类通常会包括一个委托(delegate)对象,该对象可以实现一个协议,该协议中可能包含一个实现文字输入的自动完成方法。若这个委托对象实现了这个方法,那么文本框类就会在适当的时候触发自动完成事件,并调用这个方法用于自动完成功能。
Objective-C中协议的概念与Java中接口的概念并不完全相同,即一个类可以在不声明它匹配某个协议的情况下,实现这个协议所包含的方法,也即实质上匹配这个协议,而这种差别对外部代码而言是不可见的。正式协议的声明不提供实现,它只是简单地表明匹配该协议的类实现了该协议的方法,保证调用端可以安全调用方法。
语法
协议以关键字@protocol作为区块起始,@end结束,中间为方法列表。
@protocol Locking
- (void)lock;
- (void)unlock;
@end
这是一个协议的例子,多线程编程中经常要确保一份共享资源同时只有一个线程可以使用,会在使用前给该资源挂上锁 ,以上即为一个表明有"锁"的概念的协议,协议中有两个方法,只有名称但尚未实现。
下面的SomeClass宣称他采纳了Locking协议:
@interface SomeClass : SomeSuperClass <Locking>
@end
一旦SomeClass表明他采纳了Locking协议,SomeClass就有义务实现Locking协议中的两个方法。
@implementation SomeClass
- (void)lock {
// 實現lock方法...
}
- (void)unlock {
// 實現unlock方法...
}
@end
由于SomeClass已经确实遵从了Locking协议,故调用端可以安全的发送lock或unlock消息给SomeClass实体变量,不需担心他没有办法回应消息。
动态类型
Objective-C具备动态类型:即消息可以发送给任何对象实体,无论该对象实体的公开接口中有没有对应的方法。对比于C++这种静态类型的语言,编译器会挡下对(void*)指针调用方法的行为。但在Objective-C中,你可以对id发送任何消息(id很像void*,但是被严格限制只能使用在对象上),编译器仅会发出"该对象可能无法回应消息"的警告,程序可以通过编译,而实际发生的事则取决于运行期该对象的真正形态,若该对象的确可以回应消息,则依旧运行对应的方法。
一个对象收到消息之后,他有三种处理消息的可能手段,第一是回应该消息并运行方法,若无法回应,则可以转发消息给其他对象,若以上两者均无,就要处理无法回应而抛出的例外。只要进行三者之其一,该消息就算完成任务而被丢弃。若对"nil"(空对象指针)发送消息,该消息通常会被忽略,取决于编译器选项可能会抛出例外。
虽然Objective-C具备动态类型的能力,但编译期的静态类型检查依旧可以应用到变量上。以下三种声明在运行时效力是完全相同的,但是三种声明提供了一个比一个更明显的类型信息,附加的类型信息让编译器在编译时可以检查变量类型,并对类型不符的变量提出警告。
下面三个方法,差异仅在于参数的形态:
- setMyValue:(id) foo;
id形态表示参数"foo"可以是任何类的实例。
- setMyValue:(id <aProtocol>) foo;
id<aProtocol>表示"foo"可以是任何类的实例,但必须采纳"aProtocol"协议。
- setMyValue:(NSNumber*) foo;
该声明表示"foo"必须是"NSNumber"的实例。
转发
Objective-C允许对一个对象发送消息,不管它是否能够响应之。除了响应或丢弃消息以外,对象也可以将消息转发到可以响应该消息的对象。转发可以用于简化特定的设计模式,例如观察者模式或代理模式。
Objective-C运行时在Object中定义了一对方法:
转发方法
- (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
- (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
响应方法
- (retval_t) performv:(SEL) sel :(arglist_t) args; // with GCC
- (id) performv:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
类别(Category)
文章参考
https://www.runoob.com/w3cnote/objective-c-tutorial.html
相关阅读
sqlmap依托于python,首先下载python 和 sqlmap下载地址python 安装一步步默认即可,安装完后将sqlmap 放入python根目录下这还没结束
1.先简单说一下购物车对前台电商产品经理来说,设计一个好的购物车,整个网站的灵魂基本上就有了,“设计购物车”可绝对不是说设计购物
目录 前言... 3 软件测试流程... 3 提取测试点... 4 设计测试用例与用例评审... 4 测试类型选择... 5 测试执行与缺陷管理... 7
使用beego创建新项目beego 的项目基本都是通过 bee 命令来创建的,所以在创建项目之前确保你已经安装了 bee 工具和 beego。如果
翻译自 DESCRIBEdescribe命令列出指定表的列定义,视图或同义词,或指定函数或存储过程的详述。语法:desc[ribe] {[模式.]对象