1. 第一个objective-c程序
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
(1)#import 语句类似c语言中的#include语句,用来通知编译器查询头文件中相应的定义代码。但是它保证了该头文件只被包含一次,无论该命令在该文件中出现了多少次。
(2)NSLog这个函数类似c语言中的printf函数,其中@富豪是objective-c在标准c的基础上添加的特性之一,@符号意味引号内的字符串应作为cocoa的NSString元素来处理。
(3)autoreleasepool是objective-c的内存管理方法,用来防止内存泄露,autorelease实际上吧对release的调用延迟了,对于每一个autorelease,系统只是把该object放入了当前的autorelease pool中,当该pool释放时,该pool中的所有object会被调用release。
2. objective-c中创建自定义类
在objective-c中@interface声明类的接口,在@implementation中定义类的实现。如CCategory类,将声名定义在CCategory.h文件中,而将CCategory实现写在CCategory.m文件中。
(1) CCategory.h
#import <Foundation/Foundation.h>
@interface CCategory : NSObject
@end
(2) CCategory.m
#import "CCategory.h"
@implementation CCategory
@end
(3) 关于继承,其中CCategory类继承于NSObject类,这点类似于java。其声明语法为:
@interface CCategory : NSObject
但是不同于java,objective-c中不止有NSObject一个基类,还有NSProxy等等。当前objective-c同java一致,不支持c++中支持的多继承,而在objective-c中,如果你想达到多继承的效果,可以使用类别和协议,这两个在objective-c的独有特性。
3. 带私有变量和方法的自定义类
#import <Foundation/Foundation.h>
@interface CCategory : NSObject
{
@private
int m_type;
float m_value;
}
- (int) getType;
- (float) getValue;
- (void) setType : (int) type;
- (void) setStr : (float) value;
@end
#import "CCategory.h"
@implementation CCategory
- (int) getType {
return m_type;
}
- (float) getValue {
return m_value;
}
- (void) setType : (int) type {
m_type = type;
}
- (void) setStr : (float) value {
m_value = value;
}
// override description function
- (NSString *)description {
return [ [NSString alloc] initWithFormat: @"type [%d], value [%f]", m_type, m_value ];
}
@end
#import <Foundation/Foundation.h>
#import "CCategory.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
id category = [CCategory new];
[category setType:1];
[category setStr:1.23];
NSLog(@"%@", category);
}
return 0;
}
(1)在obejctive-c中,可以使用@private修饰私有变量。在objective-c中,所有实例变量默认都是私有的,所有实例方法默认都是公有的。
(2) 关于类方法的声明, - (void) setType : (int) type;
+ 声明类的实例方法
- 声明类的静态方法
(3)NSLog输出任意对象,重写desciption方法,这个类似于java中继承于Object的类重写toString方法,当nslog输出类时,会调用该方法输出。
(4)在objective-c中方法调用被称为消息传递,[class functionName : parameter]。
4. 使用属性@property简化代码。
(1)之前对于某个类私有变量,我们在定义该变量时,需要定义变量setter/getter方法,这样是的程序代码大大增加,而从objective-c2.0开始,我们可以让系统自动生成变量setter/getter方法。
(2)@property语法声明为:@property (attribute) Vartype Varname;
其中attribute包括:a. 读写属性(readwrite/readonly)以及(getter=name)、(setter=name); b. setter语意:(assign/retain/copy);c.原子性:(non)atomic
(3)采用@property与自定义setter和getter方法其实是等价的,但是编译器会优先查找自定义的setter/getter方法,如果找不到会自动使用@property对应的属性。如:
@property (nonatomic, copy) NSString* name;
这条语句等价于
- void setName: (NSString*) newName {
if(newName != name) {
[name release];
name = [newName copy];
}
}
- (NSString*) name {
return name;
}
a. 读写属性中,readwrite可以获取实例变量的值,对于@synthesize,编译器会自动为该变量生成getter/setter方法,而readonly会自动生成getter,而不会生成setter方法。
b. setter语意assign/retain/copy决定了以何种方式对数据成员赋予新值。对于Objective-c中一般object最好使用retain,一些特别的object(如:NSString)使用copy,assign关键字代表setter直接赋值,而不是复制或者保留它,更不需要进行引用计数。
c. atomicity默认值是atomic,读取函数为原子操作。atomic是保证读取变量是线程安全的,即它保证每次getter/setter的操作都会正确的执行完毕,而不用担心其他线程在你getter的时候进行setter。如果不在多线程中使用,这些声明可以提高访问方法的调用速度。特别是在iphone\ipad等移动设备中。
d. @property默认的行为有:atomic, readwrite, assign。
e. 其实retain和copy的区别本质上是深拷贝与浅拷贝的区别。
5. 内存管理
(1)引用计数技术,这个技术跟c++智能指针类似,每个对象都有一个与之关联的整数,称之为引用计数器,当某段代码需要访问一个对象时,该代码就将该对象的保留计数器值+1,每段代码结束对象访问时,对象计数器-1,表示它不再访问该对象。当计数器值为0时,表示不再有代码访问该对象了。
(2)当使用alloc、new方法或者通过copy消息时,创建一个对象,对象的保留计数器设置为1。要增加对象的保留计数器,就给对象发送retain消息,要减少保留计数器的值,就给对象发送release消息。当一个对象的保留计数器值为0时,就会调用对象的dealloc方法,释放掉对象的相关资源。retainCount消息返回对象的保留计数器值。
- (id) init;
- (void) dealloc;
这两个消息类似c++中的对象构造函数和析构函数。分别在对象创建和销毁时调用。
(3)autorelease方法,该消息配合自动释放池使用,当给一个对象发送autorelease消息时,实际上是将该对象添加到自动释放池中。当自动释放池被销毁时,会向池中所有对象发送release消息。
可通过@autoreleasepool关键字和通过NSAutoReleasePool对象2种方式创建。
(4)如果你保留了某个对象,就需要最终释放或者自动释放该对象。必须保持retian方法和release方法的使用次数相同。
(5)虽然目前objective-c支持自动垃圾回收,但是无法用在ios应用程序上。实际上在ios开发中,苹果公司建议你不要在自己的代码中使用autorelease方法,也不要使用会自动释放对象的一些便利方法。
5. NSString中的常用方法包括
(1) [str uppercaseString]
(2) [str lowercaseString]
(3) [str capitalizedString]
(4) [str1 isEqualToString: str2]
(5) NSComparisonResult result = [str1 compare:str2];
NSOrderedAscending NSOrderedSame NSOrderedDescending
(6) [str hasPrefix:@“aaa”]
(7) [str hasSuffix:@“bbb”]
(8) [str length]
(9) [str characterAtIndex:2]
6. @class 创建了类的前向引用,对于循环依赖问题,@class很有用,即a类使用b类,b类也使用a类,如果试图通过#import语句,让这两个类相互引用,那就会出现编译错误。但是如果在a.h中使用@class B,在b.h中使用@class a,那么这两个类就可以相互引用了。