1.函数调用
不带参数
startedBlock();
带参数
NSLog(@"decrypted string: %@", str);
CGRectMake(0,0,0,0);
2.传递消息
不带参数
[obj method];
带一个参数:
[counter increase:1];
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue {...} //定义方法
[myObj setColorToRed: 1.0 Green: 0.8 Blue: 0.2];
消息嵌套
UINavigationBar *bar = [[[UINavigationBar alloc] init] autorelease];
3.接口与实现
@interface MyClass {
int memberVar1;
id memberVar2;
}
-(return_type) instance_method1;
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
@implementation MyClass {
int memberVar3;
}
-(return_type) instance_method1 {
....
}
-(return_type) instance_method2: (int) p1 {
....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
....
}
@end
4.类方法(不需要实例就能调用)
@interface MyClass
+(void) sayHello;
@end
@implementation MyClass
+(void) sayHello {
NSLog(@"Hello, World");
}
@end
使用
[MyClass sayHello];
5.实例方法
@interface MyClass : NSObject
-(void) sayHello;
@end
@implementation MyClass
-(void) sayHello {
NSLog(@"Hello, World");
}
@end
使用
mycls = [MyClass new];//int age=[en getAge]; NSString* name=[en getName];
MyClass *mycls = [[MyClass alloc] init]
[mycls sayHello];
/---------------------------------------------------------------------------------------------------------------
6.在Objective-C里,selector主要用来做两类事情
绑定控件触发的动作
@implementation DemoViewController
- (void)downButtonPressed:(id)sender {//响应“按钮被按下事件”的方法
UIButton *button = (UIButton*)sender;
<a href="" class="button small"></a>;
}
- (void)drawAnButton {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = _frame;
btn.tag = 1;
btn.backgroundColor = [UIColor clearColor];
[btn addTarget: self
action: @selector(downButtonPressed:)
forControlEvents: UIControlEventTouchUpInside];//当这个按钮被按下时,触发downButtonPressed:方法
}
@end
延时异步执行
@implementation ETHotDealViewController
- (void)viewDidLoad {
//获取数据源
HotDealDataSource *ds = [[HotDealDataSource alloc]init];
[ds reload];
_items = ds.items;
[self performSelector: @selector(refreshTable)
withObject: self
afterDelay: 0.5];//延迟0.5秒调用refreshTable方法
}
-(void)refreshTable
{
[self.tableView reloadData];
}
@end
/---------------------------------------------------------------------------------------------------------------
7.继承
@interface MyClass : NSObject
@end
8.协议(协议是一组没有实现的方法列表)
@protocol Printable
-(void)print:(NSString)str;
@end
协议继承
@protocol Printable <NSObject>
-(void)print:(NSString)str;
@end
可选方法
@protocol Printable
@optional
-(void)print:(NSString)str;
@end
协议实现
@interface class MyClass : NSObject <Printable, Drawable>
@end
分类(给一个已经存在的类增加方法,而不用去改它的源码)
@interface NSObject (Json)
-(NSString)toJson;
@end
implementation NSObject (Json)
-(NSString)toJson {
//...
}
@end
import "NSObject+Json.h"
@implatementation XYZController
-(void)test {
NSObject *obj = [[NSObject alloc]init];
NSString *str = [obj toJson];
}
@end
NSObject+Json+XML.h
@interface NSObject (Json)
-(NSString)toJson;
@end
@interface NSObject (XML)
-(NSString)toXML;
@end
实现文件:NSObject+Json+XML.m
@implementation NSObject (Json)
-(NSString)toJson {
//...
}
@end
@implementation NSObject (XML)
-(NSString)toXML {
//...
}
@end
使用:
import "NSObject+Json+XML.h"
@implatementation XYZController
-(void)test {
NSObject *obj = [[NSObject alloc]init];
NSString *json = [obj toJson];
NSString *xml = [obj toXML];
}
@end
nteger.h
#import <objc/Object.h>
@interface Integer : Object
{
@private
int integer;
}
@property (assign, nonatomic) integer;
@end
Integer.m
#import "Integer.h"
@implementation Integer
@synthesize integer;
@end
Arithmetic.h
#import "Integer.h"
@interface Integer(Arithmetic)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end
Arithmetic.m
#import "Arithmetic.h"
@implementation Integer(Arithmetic)
- (id) add: (Integer *) addend
{
self.integer = self.integer + addend.integer;
return self;
}
- (id) sub: (Integer *) subtrahend
{
self.integer = self.integer - subtrahend.integer;
return self;
}
@end
Display.h
#import "Integer.h"
@interface Integer(Display)
- (id) showstars;
- (id) showint;
@end
Display.m
#import "Display.h"
@implementation Integer(Display)
- (id) showstars
{
int i, x = self.integer;
for(i=0; i < x; i++)
printf("*");
printf("\n");
return self;
}
- (id) showint
{
printf("%d\n", self.integer);
return self;
}
@end
main.m
#import "Integer.h"
#import "Arithmetic.h"
#import "Display.h"
int
main(void)
{
Integer *num1 = [Integer new], *num2 = [Integer new];
int x;
printf("Enter an integer: ");
scanf("%d", &x);
num1.integer = x;
[num1 showstars];
printf("Enter an integer: ");
scanf("%d", &x);
num2.integer = x;
[num2 showstars];
[num1 add:num2];
[num1 showint];
return 0;
}
Cocoa是Mac OS App的开发框架,Cocoa Touch是iOS开发用的框架
Cocoa包含Foundation和AppKit框架,可用于开发Mac OS X系统的应用程序。
Cocoa Touch包含Foundation和UIKit框架,可用于开发iPhone OS系统的应用程序。
Cocoa是 Mac OS X 的开发环境,Cocoa Touch是 iPhone OS的开发环境
Cocoa实际上由三个框架组成:
1)Foundation框架;
2)便于使用数据库存储和管理数据的Core Data框架;
3)Application Kit(AppKit)框架。
Cocoa Touch实际上由三个框架组成:
1)Foundation框架;
2)便于使用数据库存储和管理数据的Core Data框架;
3)UIKit框架。
Retina:表示视网膜屏,iPhone(Retina)代表iPhone4,iPhone4S
4-Inch:表示4英寸的iPhone,iPhone(Retina 4-Inch)就是iPhone 5
自定义初始化
- (id) init {
if ( self=[super init] ) { // 必须调用父类的init
// do something here ...
}
return self;
}
- setMyValue:(id <aProtocol>) foo;
id<aProtocol>表示“foo”可以是任何类的实例
- setMyValue:(NSNumber*) foo;
该声明表示“foo”必须是“NSNumber”的实例
转发方法:
- (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
Forwarder.h
#import <objc/Object.h>
@interface Forwarder : Object
{
id recipient; //该对象是我们希望转发到的对象。
}
@property (assign, nonatomic) id recipient;
@end
Forwarder.m
#import "Forwarder.h"
@implementation Forwarder
@synthesize recipient;
- (retval_t) forward: (SEL) sel : (arglist_t) args
{
/*
*检查转发对象是否响应该消息。
*若转发对象不响应该消息,则不会转发,而产生一个错误。
*/
if([recipient respondsTo:sel])
return [recipient performv: sel : args];
else
return [self error:"Recipient does not respond"];
}
Recipient.h
#import <objc/Object.h>
// A simple Recipient object.
@interface Recipient : Object
- (id) hello;
@end
Recipient.m
#import "Recipient.h"
@implementation Recipient
- (id) hello
{
printf("Recipient says hello!\n");
return self;
}
@end
main.m
#import "Forwarder.h"
#import "Recipient.h"
int main(void)
{
Forwarder *forwarder = [Forwarder new];
Recipient *recipient = [Recipient new];
forwarder.recipient = recipient; //Set the recipient.
/*
*转发者不响应hello消息!该消息将被转发到转发对象。
*(若转发对象响应该消息)
*/
[forwarder hello];
return 0;
}
扮演
#ifndef XXX
#define XXX ...
#endif
惯用法,或MSVC中的
#pragma once
属性
可以提供储存方法包括“assign”,“copy”或“retain”(简单的赋值、复制或增加1引用计数)。默认的属性是原子的,即在访问时会加锁以避免多线程同时访问同一对象,也可以将属性声明为“nonatomic”(非原子的),避免产生锁。
@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
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]);
}
OC数据类型分为:
基本数据类型(int、float、double和char类型),%e, %g
对象类型(类或协议所声明的指针类型,),NSString是对象类型,所以在定义的时候要使用 NSString *name 方式
id类型(任何类型)
%@ 对象
%d, %i 整数
%u 无符整形
%f 浮点/双字
%x, %X 二进制整数
%o 八进制整数
%zu size_t
%p 指针
%e 浮点/双字 (科学计算)
%g 浮点/双字
%s C 字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字
%e 是实数,用科学计数法计的
@property是一种代码生成机制,能够生成不同类型的getter和setter方法//申明
用. 操作来获取对象属性值和属性设置值就要使用@property
@property 要和@synthesize一同使用
#import <Foundation/Foundation.h>
#import "Engine.h"
@interface MyCar : NSObject
{
int value;
float fValue;
NSString* carName;
Engine* en;
}
@property (nonatomic) int value;
@property (nonatomic) float fValue;
@property (nonatomic) NSString* carName;
@property (retain) Engine* en;
@end
#import "MyCar.h"
@implementation MyCar
@synthesize value;
@synthesize fValue;
@synthesize carName;
@synthesize en;
@end
@property中的attribute简单介绍
readonly-只读,只能读取而不能设定值(不能用setXXXX的函式)。
readwrite-可读可写(默认)。
assign-在设值时替换新旧变量(默认)。
retain-在设值时retain新的变量,release旧变量。
copy-在设值时copy一份新变量,release旧变量。
nonatomic-默认為atomic
+(id) alloc; 注意这里的alloc是一个类方法,调用alloc方法之后会在内存中分配一块空间,并且引用计数会设置为1
+(id) init; 调用init方法表示初始化对象
-(void) dealloc; 这里注意一下dealloc不是一个类方法,而是一个实例方法。dealloc 方法用于销毁对象,当引用计数为0的时候系统会自动调用dealloc方法销毁对象
-(void) release; 调用这个方法用于释放对象的引用,引用计数会-1
-(void) retain ;调用这个方法用于将引用计数+1
- (NSUInteger)retainCount; 用于获取一个对象当前被多少对象拥有
- (NSUInteger)length; 方法可以获得字符串的长度
第一种方式NSString *abc=[str6 substringWithRange:NSMakeRange(i,1)];
第二种方式unichar c=[str6 characterAtIndex:i];
第二种方式出现中文%c输出则为乱码,必须使用%C才能正确的输出中文
字符串的比较使用isEqualToString
BOOL flag=[str1 isEqualToString:str2];
if(flag){
NSLog(@"%@",@"字符串相等");
}
compare方法也用于比较,但是会返回三个值:
NSOrderedSame: 判断两者类容是否完全一样
NSOrderedAscending: 判断两者大小,前者小于后者的时候为真
NSOrderedDescending:判断两者大小,前者大于后者的时候为真
NSString *str3=@"abc";
NSString *str4=@"acc";
result=[str3 compare:str4]==NSOrderedAscending;
NSLog(@"result:%d",result);
hasPrefix 判断字符串是否以某个字符串开头
hasSuffix 判断字符串是否以某个字符串结尾
if([str1 hasPrefix:@"Object"]){
NSLog(@"字符串:%@是以%@开头",str1,@"Object");
}
substringToIndex: 截取从索引0到特定位置处的字符串
substringFromIndex: 截取从特定位置到字符串末尾的字符串
substringWithRange:从特定位置开始截取特定长度的字符
NSString *str2=[str1 substringToIndex:3];
NSRange 获取NSRange的实例要使用NSRange range=NSMakeRange(2,100)
遍历
for(int i=0;i<count;i++){
NSString *abc=[str6 substringWithRange:NSMakeRange(i,1)];
NSLog(@"%@",abc);
}
for(int i=0;i<count;i++){
unichar c=[str6 characterAtIndex:i];
NSLog(@"中文情况=%c",c);
uppercaseString将字符串转化为大写
lowercaseString将字符串转化为小写
capitalizedString将字符串首字母转化为大写
NSString *str2=[str1 uppercaseString]
NSMutableString *str=[NSMutableString stringWithString:@"Obejct C"];
[str appendString:@"NSMutableString 字符串"];
[str appendFormat:@" --我的名字:%@ , 年龄 %d",@"Object C",10];
NSRange range= [str rangeOfString:@"Mutable"];
[str deleteCharactersInRange:range];
[str insertString:str2 atIndex:6];
intValue用于将字符串类型转换为int 类型
integerValue用于将字符串类型转换为NSInteger 类型
floatValue用于将字符串类型转换为float类型
doubleValue用于将字符串类型转换为double类型
int value1=[str1 intValue];
static 属性应该定义在implementation中,而且写在implementation之外或者方法之中
+(void) hello
{
static int count;
count++;
NSLog(@"static = %i",count);
}
-(void) write
{
static int myage=0;
myage++;
NSLog(@"年龄:%i",myage);
}
#import "Person.h"
static int count;
@implementation Person
@end
- (返回值类型) 方法名: 参数,...
适用静态方法 就是将 "-" 改为 "+" 即可。
+(void) hello; 在interface中定义如上方法签名,而在implementation中实现这个方法。
在Object C中NSArray 只能存放对象类型的指针,不能存放int,char,double等基本数据类型。
NSArray *items=[NSArray arrayWithObjects:@"abc",@"cdf", nil];
[items count]
[items objectAtIndex:0]
for(int i=0;i<[items count];i++){
NSLog(@"%@",[items objectAtIndex:i]);
}
SMutableArray *mutItems=[NSMutableArray arrayWithCapacity:2];
[mutItems addObject:@"abc"];
[mutItems insertObject:@"wang" atIndex:1];
- (void)removeObject:(id)anObject inRange:(NSRange)range;设置在一定范围内删除,如果在这个范围内没有匹配的元素则什么都不删除。
- (void)removeObject:(id)anObject;删除指定元素
- (void)removeObjectsInArray:(NSArray *)otherArray;删除数组中指定的元素
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;删除指定索引位置的元素
NSRange range=NSMakeRange(0, 2);
[mutItems removeObject:@"wang" inRange:range];
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject; 可以使用这个方法来替换某个索引位置的元素
[mutItems replaceObjectAtIndex:1 withObject:@"FFFFFFFFFFFFFF"];
Set集合的搜索速度要比Array速度要快
NSNumber *num=[NSNumber numberWithInteger:2345];
NSSet *set=[NSSet setWithObjects:@"abc",@"efg", num,nil];
[set count]
[set containsObject:num1];
使用objectEnumerator将集合转化为迭代器
NSEnumerator *enumr=[set objectEnumerator];
NSObject *item=[enumr nextObject];
使用方法isEqualToSet用于判断两个集合元素是否一样,返回bool值。
- (BOOL)isSubsetOfSet:(NSSet *)otherSet; 判断前者集合是不是后者的子集。在上面的例子中可以看到两个集合调用的主从关系,这里是有区别的。
- (BOOL)intersectsSet:(NSSet *)otherSet;判断两个集合是否有交集,也就是两个集合是否有相同的元素。
[setItems1 isEqualToSet:setItem2];
NSMutableSet *muSet=[NSMutableSet setWithCapacity:10];
NSNumber *number1=[NSNumber numberWithInteger:344];
[muSet addObject:number1];
NSArray *nsArray=[NSArray arrayWithObjects: [NSNumber numberWithInt:2],[NSNumber numberWithInt:3],[NSNumber numberWithInt:4], nil];
[muSet addObjectsFromArray:nsArray];
addObject 方法用于往NSMutableSet集合中添加元素,每次只能添加一个元素。
而addObjectsFromArray方法则用于将一个数组添加到NSMutableSet集合中
[muSet removeObject:[NSNumber numberWithInt:2]];
[muSet removeAllObjects];
- (void)unionSet:(NSSet *)other;用于向集合中添加另外一个集合的所有元素
- (void)minusSet:(NSSet *)other;用于删除other中包含的元素
NSDictionary *dic=[NSDictionary dictionaryWithObject:@"hechen" forKey:@"name"];
NSDictionary *dic1=[NSDictionary dictionaryWithObjectsAndKeys:@"hechen",@"name",@"25",@"age", nil];
NSDictionary *dic2=[[NSDictionary alloc] init];
[dic count]
NSEnumerator *enumer=[dic1 keyEnumerator];
NSString *key2=[enumer nextObject];
NSEnumerator *enumerObject=[dic1 objectEnumerator];
根据Key获取Value
NSString *va=[dic1 objectForKey:@"name"];
NSMutableDictionary *muDic1=[NSMutableDictionary dictionaryWithCapacity:10];
[muDic1 setObject:@"中国" forKey:@"name"];
NSEnumerator *enumerKeys=[muDic1 keyEnumerator];
[muDic1 removeObjectForKey:@"add"];
[muDic1 keyEnumerator]
[muDic1 objectForKey:key]
- (void)removeObjectsForKeys:(NSArray *)keyArray;这个方法参数为一个数组,用于删除数组中包含的key的所有元素。
往类Person中添加一个新的方法
-(void) addCate:(NSString*) cate;
[peron addName:@"hechen" andWithAge:23];
委托:将方法作为一个参数传到另外一个方法中使用
@interface Student : NSObject{
id<ProtocolName> delegate;
}
@property (retain) id<ProtocolName> delegate;
@synthesize delegate;
[delegate first];
Student *stu=[[Student alloc] init];
StudentA *stua=[[StudentA alloc] init];
stu.delegate=stua;
[stu.delegate first];
[stu setMethod];
动态判断
isMemberOfClass 用于判断是否是某个类的实例
bool flag1=[stu isMemberOfClass:[Student class]];
isKindOfClass 判断是否为某个类的实例或者某个类子类的实例
bool flag1=[stu isKindOfClass:[Student class]];
respondsToSelector 用于判断某个类型或者对象是否有能力回应(调用)指定的方法
bool flag3=[per respondsToSelector:@selector(eat)];
instancesRespondToSelector 用于判断某个对象的实例是否有能力回应(调用)指定的方法
bool flag7=[Person instancesRespondToSelector:@selector(eat)];
使用performSelector 方法可以动态的调用其方法,
[stu performSelector:@selector(eat)];
调用:[stu performSelector:@selector(speak:) withObject:@"ddddd"];
-(Person *) getPerson{
Person *p=[[Person alloc] init];
p.name=@"li";
p.age=25;
p.address=@"上海";
return p;
}
枚举
enum Body{AB,CD,EF,HG};
enum Body a,b,c,d;
enum Body{AB=0,CD=1,EF=2,HG=3};1,2,3,4
enum Body{AB=0,CD=1,EF=12,HG};0,1,12,13
[对象 performSelector:SEL变量 withObject:参数1 withObject:参数2];
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
SEL和@selector一般都是同时使用的。
SEL sel=@selector(write:andAge:);
如果方法有输入参数则需要使用: ,如果没有参数则不要:
SEL sel1=@selector(eat);
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
获取一个对象的Class
Class c=[Person class];
不带参数
startedBlock();
带参数
NSLog(@"decrypted string: %@", str);
CGRectMake(0,0,0,0);
2.传递消息
不带参数
[obj method];
带一个参数:
[counter increase:1];
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue {...} //定义方法
[myObj setColorToRed: 1.0 Green: 0.8 Blue: 0.2];
消息嵌套
UINavigationBar *bar = [[[UINavigationBar alloc] init] autorelease];
3.接口与实现
@interface MyClass {
int memberVar1;
id memberVar2;
}
-(return_type) instance_method1;
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
@implementation MyClass {
int memberVar3;
}
-(return_type) instance_method1 {
....
}
-(return_type) instance_method2: (int) p1 {
....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
....
}
@end
4.类方法(不需要实例就能调用)
@interface MyClass
+(void) sayHello;
@end
@implementation MyClass
+(void) sayHello {
NSLog(@"Hello, World");
}
@end
使用
[MyClass sayHello];
5.实例方法
@interface MyClass : NSObject
-(void) sayHello;
@end
@implementation MyClass
-(void) sayHello {
NSLog(@"Hello, World");
}
@end
使用
mycls = [MyClass new];//int age=[en getAge]; NSString* name=[en getName];
MyClass *mycls = [[MyClass alloc] init]
[mycls sayHello];
/---------------------------------------------------------------------------------------------------------------
6.在Objective-C里,selector主要用来做两类事情
绑定控件触发的动作
@implementation DemoViewController
- (void)downButtonPressed:(id)sender {//响应“按钮被按下事件”的方法
UIButton *button = (UIButton*)sender;
<a href="" class="button small"></a>;
}
- (void)drawAnButton {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = _frame;
btn.tag = 1;
btn.backgroundColor = [UIColor clearColor];
[btn addTarget: self
action: @selector(downButtonPressed:)
forControlEvents: UIControlEventTouchUpInside];//当这个按钮被按下时,触发downButtonPressed:方法
}
@end
延时异步执行
@implementation ETHotDealViewController
- (void)viewDidLoad {
//获取数据源
HotDealDataSource *ds = [[HotDealDataSource alloc]init];
[ds reload];
_items = ds.items;
[self performSelector: @selector(refreshTable)
withObject: self
afterDelay: 0.5];//延迟0.5秒调用refreshTable方法
}
-(void)refreshTable
{
[self.tableView reloadData];
}
@end
/---------------------------------------------------------------------------------------------------------------
7.继承
@interface MyClass : NSObject
@end
8.协议(协议是一组没有实现的方法列表)
@protocol Printable
-(void)print:(NSString)str;
@end
协议继承
@protocol Printable <NSObject>
-(void)print:(NSString)str;
@end
可选方法
@protocol Printable
@optional
-(void)print:(NSString)str;
@end
协议实现
@interface class MyClass : NSObject <Printable, Drawable>
@end
分类(给一个已经存在的类增加方法,而不用去改它的源码)
@interface NSObject (Json)
-(NSString)toJson;
@end
implementation NSObject (Json)
-(NSString)toJson {
//...
}
@end
import "NSObject+Json.h"
@implatementation XYZController
-(void)test {
NSObject *obj = [[NSObject alloc]init];
NSString *str = [obj toJson];
}
@end
NSObject+Json+XML.h
@interface NSObject (Json)
-(NSString)toJson;
@end
@interface NSObject (XML)
-(NSString)toXML;
@end
实现文件:NSObject+Json+XML.m
@implementation NSObject (Json)
-(NSString)toJson {
//...
}
@end
@implementation NSObject (XML)
-(NSString)toXML {
//...
}
@end
使用:
import "NSObject+Json+XML.h"
@implatementation XYZController
-(void)test {
NSObject *obj = [[NSObject alloc]init];
NSString *json = [obj toJson];
NSString *xml = [obj toXML];
}
@end
nteger.h
#import <objc/Object.h>
@interface Integer : Object
{
@private
int integer;
}
@property (assign, nonatomic) integer;
@end
Integer.m
#import "Integer.h"
@implementation Integer
@synthesize integer;
@end
Arithmetic.h
#import "Integer.h"
@interface Integer(Arithmetic)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end
Arithmetic.m
#import "Arithmetic.h"
@implementation Integer(Arithmetic)
- (id) add: (Integer *) addend
{
self.integer = self.integer + addend.integer;
return self;
}
- (id) sub: (Integer *) subtrahend
{
self.integer = self.integer - subtrahend.integer;
return self;
}
@end
Display.h
#import "Integer.h"
@interface Integer(Display)
- (id) showstars;
- (id) showint;
@end
Display.m
#import "Display.h"
@implementation Integer(Display)
- (id) showstars
{
int i, x = self.integer;
for(i=0; i < x; i++)
printf("*");
printf("\n");
return self;
}
- (id) showint
{
printf("%d\n", self.integer);
return self;
}
@end
main.m
#import "Integer.h"
#import "Arithmetic.h"
#import "Display.h"
int
main(void)
{
Integer *num1 = [Integer new], *num2 = [Integer new];
int x;
printf("Enter an integer: ");
scanf("%d", &x);
num1.integer = x;
[num1 showstars];
printf("Enter an integer: ");
scanf("%d", &x);
num2.integer = x;
[num2 showstars];
[num1 add:num2];
[num1 showint];
return 0;
}
Cocoa是Mac OS App的开发框架,Cocoa Touch是iOS开发用的框架
Cocoa包含Foundation和AppKit框架,可用于开发Mac OS X系统的应用程序。
Cocoa Touch包含Foundation和UIKit框架,可用于开发iPhone OS系统的应用程序。
Cocoa是 Mac OS X 的开发环境,Cocoa Touch是 iPhone OS的开发环境
Cocoa实际上由三个框架组成:
1)Foundation框架;
2)便于使用数据库存储和管理数据的Core Data框架;
3)Application Kit(AppKit)框架。
Cocoa Touch实际上由三个框架组成:
1)Foundation框架;
2)便于使用数据库存储和管理数据的Core Data框架;
3)UIKit框架。
Retina:表示视网膜屏,iPhone(Retina)代表iPhone4,iPhone4S
4-Inch:表示4英寸的iPhone,iPhone(Retina 4-Inch)就是iPhone 5
自定义初始化
- (id) init {
if ( self=[super init] ) { // 必须调用父类的init
// do something here ...
}
return self;
}
- setMyValue:(id <aProtocol>) foo;
id<aProtocol>表示“foo”可以是任何类的实例
- setMyValue:(NSNumber*) foo;
该声明表示“foo”必须是“NSNumber”的实例
转发方法:
- (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
Forwarder.h
#import <objc/Object.h>
@interface Forwarder : Object
{
id recipient; //该对象是我们希望转发到的对象。
}
@property (assign, nonatomic) id recipient;
@end
Forwarder.m
#import "Forwarder.h"
@implementation Forwarder
@synthesize recipient;
- (retval_t) forward: (SEL) sel : (arglist_t) args
{
/*
*检查转发对象是否响应该消息。
*若转发对象不响应该消息,则不会转发,而产生一个错误。
*/
if([recipient respondsTo:sel])
return [recipient performv: sel : args];
else
return [self error:"Recipient does not respond"];
}
Recipient.h
#import <objc/Object.h>
// A simple Recipient object.
@interface Recipient : Object
- (id) hello;
@end
Recipient.m
#import "Recipient.h"
@implementation Recipient
- (id) hello
{
printf("Recipient says hello!\n");
return self;
}
@end
main.m
#import "Forwarder.h"
#import "Recipient.h"
int main(void)
{
Forwarder *forwarder = [Forwarder new];
Recipient *recipient = [Recipient new];
forwarder.recipient = recipient; //Set the recipient.
/*
*转发者不响应hello消息!该消息将被转发到转发对象。
*(若转发对象响应该消息)
*/
[forwarder hello];
return 0;
}
扮演
#ifndef XXX
#define XXX ...
#endif
惯用法,或MSVC中的
#pragma once
属性
可以提供储存方法包括“assign”,“copy”或“retain”(简单的赋值、复制或增加1引用计数)。默认的属性是原子的,即在访问时会加锁以避免多线程同时访问同一对象,也可以将属性声明为“nonatomic”(非原子的),避免产生锁。
@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
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]);
}
OC数据类型分为:
基本数据类型(int、float、double和char类型),%e, %g
对象类型(类或协议所声明的指针类型,),NSString是对象类型,所以在定义的时候要使用 NSString *name 方式
id类型(任何类型)
%@ 对象
%d, %i 整数
%u 无符整形
%f 浮点/双字
%x, %X 二进制整数
%o 八进制整数
%zu size_t
%p 指针
%e 浮点/双字 (科学计算)
%g 浮点/双字
%s C 字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字
%e 是实数,用科学计数法计的
@property是一种代码生成机制,能够生成不同类型的getter和setter方法//申明
用. 操作来获取对象属性值和属性设置值就要使用@property
@property 要和@synthesize一同使用
#import <Foundation/Foundation.h>
#import "Engine.h"
@interface MyCar : NSObject
{
int value;
float fValue;
NSString* carName;
Engine* en;
}
@property (nonatomic) int value;
@property (nonatomic) float fValue;
@property (nonatomic) NSString* carName;
@property (retain) Engine* en;
@end
#import "MyCar.h"
@implementation MyCar
@synthesize value;
@synthesize fValue;
@synthesize carName;
@synthesize en;
@end
@property中的attribute简单介绍
readonly-只读,只能读取而不能设定值(不能用setXXXX的函式)。
readwrite-可读可写(默认)。
assign-在设值时替换新旧变量(默认)。
retain-在设值时retain新的变量,release旧变量。
copy-在设值时copy一份新变量,release旧变量。
nonatomic-默认為atomic
+(id) alloc; 注意这里的alloc是一个类方法,调用alloc方法之后会在内存中分配一块空间,并且引用计数会设置为1
+(id) init; 调用init方法表示初始化对象
-(void) dealloc; 这里注意一下dealloc不是一个类方法,而是一个实例方法。dealloc 方法用于销毁对象,当引用计数为0的时候系统会自动调用dealloc方法销毁对象
-(void) release; 调用这个方法用于释放对象的引用,引用计数会-1
-(void) retain ;调用这个方法用于将引用计数+1
- (NSUInteger)retainCount; 用于获取一个对象当前被多少对象拥有
- (NSUInteger)length; 方法可以获得字符串的长度
第一种方式NSString *abc=[str6 substringWithRange:NSMakeRange(i,1)];
第二种方式unichar c=[str6 characterAtIndex:i];
第二种方式出现中文%c输出则为乱码,必须使用%C才能正确的输出中文
字符串的比较使用isEqualToString
BOOL flag=[str1 isEqualToString:str2];
if(flag){
NSLog(@"%@",@"字符串相等");
}
compare方法也用于比较,但是会返回三个值:
NSOrderedSame: 判断两者类容是否完全一样
NSOrderedAscending: 判断两者大小,前者小于后者的时候为真
NSOrderedDescending:判断两者大小,前者大于后者的时候为真
NSString *str3=@"abc";
NSString *str4=@"acc";
result=[str3 compare:str4]==NSOrderedAscending;
NSLog(@"result:%d",result);
hasPrefix 判断字符串是否以某个字符串开头
hasSuffix 判断字符串是否以某个字符串结尾
if([str1 hasPrefix:@"Object"]){
NSLog(@"字符串:%@是以%@开头",str1,@"Object");
}
substringToIndex: 截取从索引0到特定位置处的字符串
substringFromIndex: 截取从特定位置到字符串末尾的字符串
substringWithRange:从特定位置开始截取特定长度的字符
NSString *str2=[str1 substringToIndex:3];
NSRange 获取NSRange的实例要使用NSRange range=NSMakeRange(2,100)
遍历
for(int i=0;i<count;i++){
NSString *abc=[str6 substringWithRange:NSMakeRange(i,1)];
NSLog(@"%@",abc);
}
for(int i=0;i<count;i++){
unichar c=[str6 characterAtIndex:i];
NSLog(@"中文情况=%c",c);
uppercaseString将字符串转化为大写
lowercaseString将字符串转化为小写
capitalizedString将字符串首字母转化为大写
NSString *str2=[str1 uppercaseString]
NSMutableString *str=[NSMutableString stringWithString:@"Obejct C"];
[str appendString:@"NSMutableString 字符串"];
[str appendFormat:@" --我的名字:%@ , 年龄 %d",@"Object C",10];
NSRange range= [str rangeOfString:@"Mutable"];
[str deleteCharactersInRange:range];
[str insertString:str2 atIndex:6];
intValue用于将字符串类型转换为int 类型
integerValue用于将字符串类型转换为NSInteger 类型
floatValue用于将字符串类型转换为float类型
doubleValue用于将字符串类型转换为double类型
int value1=[str1 intValue];
static 属性应该定义在implementation中,而且写在implementation之外或者方法之中
+(void) hello
{
static int count;
count++;
NSLog(@"static = %i",count);
}
-(void) write
{
static int myage=0;
myage++;
NSLog(@"年龄:%i",myage);
}
#import "Person.h"
static int count;
@implementation Person
@end
- (返回值类型) 方法名: 参数,...
适用静态方法 就是将 "-" 改为 "+" 即可。
+(void) hello; 在interface中定义如上方法签名,而在implementation中实现这个方法。
在Object C中NSArray 只能存放对象类型的指针,不能存放int,char,double等基本数据类型。
NSArray *items=[NSArray arrayWithObjects:@"abc",@"cdf", nil];
[items count]
[items objectAtIndex:0]
for(int i=0;i<[items count];i++){
NSLog(@"%@",[items objectAtIndex:i]);
}
SMutableArray *mutItems=[NSMutableArray arrayWithCapacity:2];
[mutItems addObject:@"abc"];
[mutItems insertObject:@"wang" atIndex:1];
- (void)removeObject:(id)anObject inRange:(NSRange)range;设置在一定范围内删除,如果在这个范围内没有匹配的元素则什么都不删除。
- (void)removeObject:(id)anObject;删除指定元素
- (void)removeObjectsInArray:(NSArray *)otherArray;删除数组中指定的元素
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;删除指定索引位置的元素
NSRange range=NSMakeRange(0, 2);
[mutItems removeObject:@"wang" inRange:range];
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject; 可以使用这个方法来替换某个索引位置的元素
[mutItems replaceObjectAtIndex:1 withObject:@"FFFFFFFFFFFFFF"];
Set集合的搜索速度要比Array速度要快
NSNumber *num=[NSNumber numberWithInteger:2345];
NSSet *set=[NSSet setWithObjects:@"abc",@"efg", num,nil];
[set count]
[set containsObject:num1];
使用objectEnumerator将集合转化为迭代器
NSEnumerator *enumr=[set objectEnumerator];
NSObject *item=[enumr nextObject];
使用方法isEqualToSet用于判断两个集合元素是否一样,返回bool值。
- (BOOL)isSubsetOfSet:(NSSet *)otherSet; 判断前者集合是不是后者的子集。在上面的例子中可以看到两个集合调用的主从关系,这里是有区别的。
- (BOOL)intersectsSet:(NSSet *)otherSet;判断两个集合是否有交集,也就是两个集合是否有相同的元素。
[setItems1 isEqualToSet:setItem2];
NSMutableSet *muSet=[NSMutableSet setWithCapacity:10];
NSNumber *number1=[NSNumber numberWithInteger:344];
[muSet addObject:number1];
NSArray *nsArray=[NSArray arrayWithObjects: [NSNumber numberWithInt:2],[NSNumber numberWithInt:3],[NSNumber numberWithInt:4], nil];
[muSet addObjectsFromArray:nsArray];
addObject 方法用于往NSMutableSet集合中添加元素,每次只能添加一个元素。
而addObjectsFromArray方法则用于将一个数组添加到NSMutableSet集合中
[muSet removeObject:[NSNumber numberWithInt:2]];
[muSet removeAllObjects];
- (void)unionSet:(NSSet *)other;用于向集合中添加另外一个集合的所有元素
- (void)minusSet:(NSSet *)other;用于删除other中包含的元素
NSDictionary *dic=[NSDictionary dictionaryWithObject:@"hechen" forKey:@"name"];
NSDictionary *dic1=[NSDictionary dictionaryWithObjectsAndKeys:@"hechen",@"name",@"25",@"age", nil];
NSDictionary *dic2=[[NSDictionary alloc] init];
[dic count]
NSEnumerator *enumer=[dic1 keyEnumerator];
NSString *key2=[enumer nextObject];
NSEnumerator *enumerObject=[dic1 objectEnumerator];
根据Key获取Value
NSString *va=[dic1 objectForKey:@"name"];
NSMutableDictionary *muDic1=[NSMutableDictionary dictionaryWithCapacity:10];
[muDic1 setObject:@"中国" forKey:@"name"];
NSEnumerator *enumerKeys=[muDic1 keyEnumerator];
[muDic1 removeObjectForKey:@"add"];
[muDic1 keyEnumerator]
[muDic1 objectForKey:key]
- (void)removeObjectsForKeys:(NSArray *)keyArray;这个方法参数为一个数组,用于删除数组中包含的key的所有元素。
往类Person中添加一个新的方法
-(void) addCate:(NSString*) cate;
[peron addName:@"hechen" andWithAge:23];
委托:将方法作为一个参数传到另外一个方法中使用
@interface Student : NSObject{
id<ProtocolName> delegate;
}
@property (retain) id<ProtocolName> delegate;
@synthesize delegate;
[delegate first];
Student *stu=[[Student alloc] init];
StudentA *stua=[[StudentA alloc] init];
stu.delegate=stua;
[stu.delegate first];
[stu setMethod];
动态判断
isMemberOfClass 用于判断是否是某个类的实例
bool flag1=[stu isMemberOfClass:[Student class]];
isKindOfClass 判断是否为某个类的实例或者某个类子类的实例
bool flag1=[stu isKindOfClass:[Student class]];
respondsToSelector 用于判断某个类型或者对象是否有能力回应(调用)指定的方法
bool flag3=[per respondsToSelector:@selector(eat)];
instancesRespondToSelector 用于判断某个对象的实例是否有能力回应(调用)指定的方法
bool flag7=[Person instancesRespondToSelector:@selector(eat)];
使用performSelector 方法可以动态的调用其方法,
[stu performSelector:@selector(eat)];
调用:[stu performSelector:@selector(speak:) withObject:@"ddddd"];
-(Person *) getPerson{
Person *p=[[Person alloc] init];
p.name=@"li";
p.age=25;
p.address=@"上海";
return p;
}
枚举
enum Body{AB,CD,EF,HG};
enum Body a,b,c,d;
enum Body{AB=0,CD=1,EF=2,HG=3};1,2,3,4
enum Body{AB=0,CD=1,EF=12,HG};0,1,12,13
[对象 performSelector:SEL变量 withObject:参数1 withObject:参数2];
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
SEL和@selector一般都是同时使用的。
SEL sel=@selector(write:andAge:);
如果方法有输入参数则需要使用: ,如果没有参数则不要:
SEL sel1=@selector(eat);
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
获取一个对象的Class
Class c=[Person class];