CG@CPPBLOG

/*=========================================*/
随笔 - 76, 文章 - 39, 评论 - 137, 引用 - 0
数据加载中……

2013年11月23日

用OBJC编程 9 - Conventions

用OBJC编程 9 - Conventions

  • 有些名字在你的app里必须唯一
  • 类名必须唯一,因此请使用前缀,建议使用三个字母的前缀,避免和Cocoa框架冲突,类名使用名词
  • 方法名不要前缀,以小写字母开始,多个参数时,其它参数要有参数名。第一个单词指明方法的效果,或者一个行为等等。
  • 如果方法参数包括error,它应该是最后一个参数,如果参数包括一个block,它应该在最后,不应该有多个block参数。方法名长度要适中。
  • 避免缩写
  • 分类里的方法名加上前缀,避免冲突。
  • 局部变量应该是唯一的。
  • 访问器的名称要符合惯例。否则在KVC时可能不能工作。
  • 工厂方法名应该以类名开始(或者父类的类名)

posted @ 2013-11-23 11:33 cuigang 阅读(153) | 评论 (0)编辑 收藏

用OBJC编程 8 - Dealing with Errors

用OBJC编程 8 - Dealing with Errors

使用NSError,

委托方法会产生Error
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
NSError包括错误码,错误业务领域domain和描述。为保证每个错误码唯一,使用了domain,NSURLConnection的domain是NSURLErrorDomain

通过引用参数传递Error
-(BOOL)WriteToURL:(NSURL *)aURL option:(NSDataWritingOptions)mask error:(NSError**) errorPtr;
//////////////////////////
NSError *anyError;
BOOL sucess = [receivedData writeToURL:someLocalFileURL option:0 error:&anyError];
if(!success){
    NSLog(@"Write failed with error: %@", anyError);
    
//present error to user
}
// 如果writeToURL发生错误,返回NO,并且更新anyError
// 如果你对error不感兴趣,可以传递NULL

产生你自己的error
NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
NSString *desc = NSLocalizedString(@"Unable to,,,"@"");
NSDictionary *userInfo = @{NSLocalizedDescriptionKey : desc};

NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo];
//////////////////////
- (BOOL) doSomethingThatMayGenerateAnError:(NSError **)errorPtr;

//////////////////
-(BOOL)doSomethingThatMayGenerateAnError:(NSError **)errorPtr{
  
//,,,
  
// error occurred
  if(errorPtr){
    
*errorPtr = [NSError errorWithDomain:,,,  code:,,, userInfo:,,,];
  }
  
return NO;
}

使用异常
OBJC像其他语言一样支持异常,NSException和NSError一样是一个对象
@try{
   
// 可能导致异常
}
@catch (NSException *exception){
   
// 处理异常
}
@finally{
   
// 清理,处理无异常情况
}





posted @ 2013-11-23 11:14 cuigang 阅读(189) | 评论 (0)编辑 收藏

2013年11月21日

用OBJC编程 7 - Working with Blocks

用OBJC编程 7 - Working with Blocks

Block 是语言级别的特性。它是一个OBJC的对象,可以被加入容器如NSArray或NSDictionary。它可以捕获所处作用域的数值,非常类似其它语言的closure或者lambda。

语法
^{
    NSLog(@"This is a block");
}

可以像函数指针那样声明一个变量来持有这个block
void (^simpleBlock)(void);
simpleBlock = ^{
   NSLog(@"This is a block");
}; // 注意这里有一个分号

也可以这样写
void (^simpleBlock)(void= ^{
    NSLog(@"This is a block");
};

调用这个block
simpleBlock();

带上参数和返回值
^double (double firstValue, double secondValue){
    
return firstValue*secondValue;
}
// ,,,,,,,,,,,
double (^multiplyTwoValues)(doubledouble= 
    
^(double firstValue, double secondValue) { // 返回值类型可以省略
          return firstValue*secondValue;
     };

double result = multiplyTwoValues(2,4);
NSLog(@"The result is %f", result);

捕获Enclosing Scope内的值,一旦捕获,这个值就不会变化,即便后续改变这个值
-(void)testMethod{
  
int anInteger = 42;
  
void (^testBlock)(void= ^{
       NSLog(@"Integer is: %i", anInteger);
  }
  anInteger = 84;
  testBlock(); // 仍然输出42
}

使用__block
__block int anInteger = 42;
void (^testBlock)(void= ^{
  NSLog(@"Integer is: %i", anInteger);
};
anInteger = 84:
testBlock();  // output 84;

// ,,,,,,,,,,,,,

_block int anInteger = 42;
void (^testBlock)(void= ^{
  NSLog(@"Integer is: %i", anInteger); // output 42
  anInteger = 100;
};

testBlock();
NSLog(@"Value of original variable is now: %i", anInteger); // output 100;

通过参数传递Block,例如实现一个回调
-(IBAction)fetchRemoveInformation:(id)sender{
  [self showProgressIndicator];
  XYZWebTask *task = //,,,

  [task beginTaskWithCallbackBlock:^{
        [self hideProgressIndicator];
      }];
}

// beginTaskWithCallbackBlock 的定义是这样的

-(void)beginTaskWithCallbackBlock:(void)(^)(void))callbackBlock{
  
//,,,
  callbackBlock();
}

最佳实践是将block作为最后一个参数,这样便于阅读。

也可以使用typedef简化语法
typedef void (^XYZSimpleBlock)(void);
//,,,,,,,,,,,,,,,
XYZSimpleBlock anotherBlock = ^/*,,,*/ };
//,,,,,,,,,,,,
-(void)beginFetchWithCallbackBlock:(XYZSimpleBlock)callbackBlock{
    
//,,,,
    callbackBlock();
}

可以将block作为属性
@interface XYZObject : NSObject
@property (copy) void (^blockProperty)(void); // 必须使用copy
@end
//,,,,,,,,,,,,,,
self.blockProperty = ^/* ,,, */ };
self.blockProperty();

避免强引用循环
在block里捕获self,诸如在一个callback block里,会引入内存管理问题。block会会维护一个捕获对象的强引用,包括self
@interface XYZBlockKeeper : NSObject
@property (copy) void (^block)(void);
@end
////////////////////////
@implementation XYZBlockKeeper
-(void)configureBlock{
  self.block = ^{
    [self doSomething];    // 捕获了一个self的强引用
                           
// 建立了一个强引用循环
  }
}
@end

上述代码会产生一个编译警告,为了避免这种情况,最佳实践是捕获一个self的弱引用
-(void)configureBlock{
   XYZBlockKeeper * __weak weakSelf = self;
   self.block = ^ {
      [weakSelf doSomething];
   };
}

block可以简化枚举(略)
block可以简化并发任务(略)



posted @ 2013-11-21 19:20 cuigang 阅读(204) | 评论 (0)编辑 收藏

用OBJC编程 6 - Value and Collections

     摘要: 用OBJC编程 6 - Value and CollectionsOBJC里可以用基本的C原生类型,也定义了一些扩展的原生类型。BOOL类型,它的值是YES和NO,YES等于true等于1。NO等于false等于0。Cocoa定义了特殊的原生类型,如NSInteger和CGFloat。像NSInteger和NSUInteger,依赖于平台,在32位系统下是32位的,在64位下是64位的。通过API...  阅读全文

posted @ 2013-11-21 17:34 cuigang 阅读(227) | 评论 (0)编辑 收藏

用OBJC编程 5 - Working with Protocols

用OBJC编程 5 - Working with Protocols

协议定义了交互的消息
@protocol XYZPieChartViewDataSource
- (NSUInteger) numberOfSegments;
- (CGFloat)    sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
- (NSString *) titleForSegmentAtIndex:(NSUInteger)segmentIndex;
@end

数据源作为View的一个属性,只要是符合协议的对象就可以,所以类型是id。
@interface XYZPieChartView : UIView
@property (weak) id <XYZPieChartViewDataSource> dataSource;
@end
委托和数据源属性通常声明为weak,以避免强引用循环。

设置属性为一个不符合协议的对象,将会引起一个编译时警告。

可选方法,使用@optional 和 @required
@protocol XYZPieChartViewDataSource
- (NSUInteger) numberOfSegments;
- (CGFloat)    sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *) titleForSegmentAtIndex:(NSUInteger)segmentIndex;
- (BOOL)       shouldExplodeSegmentAtIndex:(NSUInteger)segementIndex;
@required
- (UIColor *)  colorForSegmentAtIndex:(NSUInteger)segementIndex;
@end

运行时检查可选方法
如果一个方法是可选的,那么在调用前应该检查它是否实现。
NSString *thisSegmentTitle; // Local object variables are automatically initialized to nil
if([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]){
    thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}

respondsToSelector: 方法用了一个selector,@selector。
如上定义一个符合协议的id类型,调用respondsToSelector,会产生一个编译时错误,解决方案是声明对象符合NSObject协议

从协议继承
最佳实践是,你的协议依从NSObject协议。NSObject对象依从NSObject协议。
一旦你的协议依从NSObject协议,那么依从你协议的任何对象都必须实现NSObject协议的方法,但因为它们应该是NSObject的子类,你就不必自己实现这些NSObject的方法。依从NSObject协议非常有用。
@protocol MyProtocol <NSObject>

@end

comform 一个协议
@interface MyClass : NSObject <MyProtocol, AnotherProtocol>

@end
如果一个类声明了大量的协议,意味着代码需要重构成多个小的类。

一旦声明依从某个协议,就必须实现所有的required方法,和需要的optional方法,否则编译器会给出警告。方法的签名必须相同。

Cocoa 和 Cocoa Touch 定义了大量的protocol
  • view的数据源协议
  • view的委托协议delegate
  • 一些类似的类,但是无继承关系,比如NSArray和NSDictionary依从NSCoding协议
  • 一些OBJC语言级特性,也依赖协议,如一个容器需要依从NSFastEnumeration协议才能使用快速枚举fast enumeration;copy的属性依从NSCopying协议,否则会得到一个运行时异常。

为匿名使用协议

有时候,一个框架的开发者为了向使用者隐藏一个类,只把它的接口通过协议暴露

id <XYZFrameworkUtility> utility = [frameworkObject anonymousUtility];

例如NSFetcheResultsController
NSInteger sectionNumber = //,,,
id <NSFetchedResultSectionInfo> sectionInfo = 
          [self.fetchedResultsController.sections objectAtIndex:sectionNumber];
NSInteger numberOfRowsInSection = [sectionInfo numberOfObjects];





posted @ 2013-11-21 09:32 cuigang 阅读(200) | 评论 (0)编辑 收藏

2013年11月20日

用OBJC编程 4 - Customizing Existing Classes

用OBJC编程 4 - Customizing Existing Classes

通过Category为类增加方法
#import "XYZPerson.h"
@interface XYZPerson (XYZPersonNameDisplayAddtions)
- (NSString *)lastNameFirstNameString;
@end
// ----------------------
#import "XYZPerson+XYZPersonNameDisplayAddtions.h"
@implementation XYZPerson (XYZPersonNameDisplayAddtions)
- (NSString *)lastNameFirstNameString{
  
return [NSString stringWithFormat:@"%@ %@", self.lastName, self.firstName];
}
@end
//-------------------------------
#import "XYZPerson+XYZPersonNameDisplayAddtions.h"
@implementation SomeObject
-(void) someMethod{
  XYZPerson *person = [[XYZPerson alloc] initWithFirstName:@"John", lastName:@"Doe"];
  NSLog(@"The people is %@", [person lastNameFirstNameString]);
}
@end

Category 可以增加任何的实例方法和类方法,但是通常不适合增加Property,虽然语法上可以声明一个Property,但不能通过Category增加一个实例变量。这意味着不能synthesize任何实例变量, 也没有存取方法。 你可以写自己的accessor,但是不能keep track property,它们存储在原始的类里。

避免名字冲突
Category 的新增方法可能会导致名字冲突,在运行时可能会出现未知的行为,为了避免这种情况,需要增加前缀
@interface NSSortDescriptor (XYZAdditions)
+ (id)xyz_sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending;
@end
//  ------ use it -------
NSSortDescriptor *descriptor = [NSSortDescriptor xyz_sortDescriptorWithKey:@"name" ascending:YES];

类扩展类似分类,但只能用于编译时有源码情况,并且必须写在实现文件里,因此不能通过这个为框架类扩展。扩展语法类似分类
@interface ClassName ()
{
    id _someCustomInstanceVariable;
}
@property NSObject *extraProperty;
@end
也叫匿名分类。不像分类那样,扩展可以增加属性和实例变量。编译器会自动synthesize accessor方法。如果你增加方法,必须实现在主要的@implementation代码块里。

可以用扩展来声明私有属性和方法
@interface XYZPerson:NSObject
@proerty (readonly) NSString *uniqueIdentifier;
-(void)assignUniqueIdentifier;
@end

/// ---------------------

@interface XYZPerson ()
@property (readwrite) NSString *uniqueIdentifier;
@end

@implementation XYZPerson
// ,,,
@end
像上面那样重复声明uniqueIdentifier为readwrite,每一个运行时的XYZPerson对象都将存在一个setter。
任何访问私有方法,或者set一个readonly属性的行为,编译器都会产生错误,但是可以通过动态运行时特性避免编译器错误,诸如调用NSObject的performSelector方法。

如果你打算构建私有方法或属性,你可以声明一个分离的头文件来声明扩展,诸如XYZPerson.h和XYZPersonPrivate.h

分类和扩展并不是定制一个类的唯一途径,也不是最好方法,要考虑可否使用子类化或者委托的方法来实现。


posted @ 2013-11-20 18:55 cuigang 阅读(145) | 评论 (0)编辑 收藏

用OBJC编程 3 -Encapsulating Data

用OBJC编程3-Encapsulating Data

@interface XYZPerson :NSObject
@property NSString *firstName;
@property NSString *lastName;
@end

/// ============

NSString *firstName = [somePerson firstName];
[somePerson setFirstName:@"Johnny"];

限定属性为只读,也可限定为readwrite,但这不必,因为缺省如是。
@property (readonly) NSString *fullname;

可以指定属性的访问器名称,多个限定词如下格式
@property (readonly, getter=isFinished) BOOL finished;

使用点语法
NSString *firstName = somePerson.firstName;
// NSString *firstName = [somePerson firstName];
somePerson.firstName = @"Johnny";
// [somePerson setFirstName:@"Johnny"];

大多数属性有一个实例变量。
缺省的读写属性会由编译器自动生成一个实例变量,以下划线开始,如_firstName;
-(void) someMethod{
  NSString *myString = @"An interesting string";
  _someString = myString;
  
// self.someString = myString;
  
// or
  
// [self setSomeString:myString];
}

可以指定实例变量的名字
@implementation YourClass
@synthesize propertyName = instanceVariableName;
@end
// ---- for example

@synthesize firstName = ivar_firstName;

如果你不指定名字,实例变量则和属性同名,前面没有下划线
@synthesize firstName;

如果你并不想提供数值给其它对象,你不必声明一个属性而使用一个实例变量
@interface SomeClass: NSObject{
  NSString *_myNonPropertyInstanceVariable;
}
@end

@implementation SomeClass{
  NSString *_anotherCustomInstanceVariable;
}

在初始化方法里访问实例变量
Setter方法会有附加效果。它们可能触发KVC通知,或者完成你定制的方法。
你应该在初始化方法里直接访问实例变量,因为对象还没有初始化完成。甚至你不应该提供定制的访问器方法给你的类提供附加效果。这样将来的子类可以很好的override这个行为。
一个典型的init方法如下
-(id)init{
  self = [super init];
  
if(self){
    
// initialize instance variables here
  }
  
return self;
}

可以指定初始化方法
-(id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName{
  self = [super init];
  
if(self){
    _firstName = aFirstName;
    _lastName = aLastName;
  }
  
return self;
}

可以指定访问方法
@property (readonly) NSString *fullName;
// -------------
-(NSString *)fullName{
 
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

如果你需要在访问器里访问实例变量,那应该直接访问。例子里延迟初始化一个对象,lazy accessor。
- (XYZObject *)someImportantObject {
  
if(!_someImportantObject){
    _someImportantObject = [[XYZObject alloc] init];
  }
  
return _someImportantObject;
}

编译器会自动synthesize一个实例变量。至少一个访问方法。如果你为readwrite属性实现了getter和setter,或者为readonly实现了getter。编译器认为你想控制属性实现,也不会再为你自动生成一个实例变量。因此,如果你仍然需要一个实例变量,你需要手动synthesize
@synthesize property = _property;

属性缺省是原子性的。atomic
@interface XYZObject : NSObject
@property NSObject *implicitAtomObject;                  // 缺省是atomic
@property (atomic) NSObject *explicitAtomicObject;       // 指明atomic
@end
缺省访问器已经解决了多线程并发的问题。

如果你定制了一个atomic, readwrite的属性的setter,而让编译器自动生成getter,将会得到一个编译时警告。

你可以声明nonatomic属性,因为不需要guarantee,处理并发,因此它的访问器比atomic属性更快。

属性的原子性并不意味着对象是线程安全的。例如firstName和LastName。

管理对象的生命周期,对象是通过指针来访问,内存是动态申请的,指针变量的生命周期不代表对象的证明周期。strong reference意味着对象和另一个对象的生命周期一样长。
属性缺省是强引用,可以指定weak。本地变量都是强引用,如果你不希望维护一个强引用,可以使用__weak
@property (weak) id delegate;
// ---------
NSObject * __weak weakVariable;

弱引用会带来不安全的行为,因为变量可能会被置为nil。
一些Cocoa类不能声明为弱引用,包括NSTextView, NSFont, NSColorSpace等,如果你需要使用这些类的一个弱引用,你需要一个unsafe_unretained声明。
@property (unsafe_unretained) NSObject *unsafePropery;
// ------------
NSObject * __unsafe_unretained unsafeReference;
unsafe引用类似weak引用,但当对象释放时,它不会被置为nil,因此你可能会持有一个悬挂指针,指向一个未知内存,向它发消息可能会导致崩溃。

copy属性
@interface XYZBadgeView : NSView
@property NSString *firstName;
@peoperty NSString *lastName;
@end

如果你这样做
NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.badgeView.firstName = nameString;
// ----
[nameString appendString:@"ny"];
这样firstName将指向一个NSMutableString,它的值可以改变了,你可以增加copy声明,避免这种情况

@interface XYZbadgeView : NSView
@property (copy) NSString *firstName;
@property (copy) NSString *lastName;
@end
// --------------------
NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.badgeView.firstName = nameString;
// ----
[nameString appendString:@"ny"];
这样firstName仍然是“John”,不会发生变化

一个被声明为copy的对象必须支持NSCopying协议。如果你要直接set一个copy属性的实例变量,例如在初始化方法里,一定要设置原始对象的copy
-(id)initWithSomeOriginalString:(NSString *)aString{
  self = [super init];
  
if(self){
     _instanceVariableForCopyProperty = [aString copy];
  }
  
return self;
}


posted @ 2013-11-20 16:49 cuigang 阅读(140) | 评论 (0)编辑 收藏

2013年11月19日

用OBJC编程 2 - working with Objects

用OBJC编程 2 - working with Objects

发送和接收消息
@interface XYZPerson : NSObject
-(void) sayHello;
@end

// implemetation
@implementation XYZPerson
- (void) sayHello{
    NSLog(@"Hello, world!");
}
@end // XYZPerson

// -----
[somePerson sayHello];

通过指针keep对象

-(void)myMethod{
  NSString *myString = // get a string from somewhere.
}

通过参数传递对象
-(void)saySomething:(NSString *)greeting;
// implementation
-(void)saySomething:(NSString *)greeting{
    NSLog(@"%@", greeting);   // "%@",用来打印对象
}

通过返回值传递
-(NSString *)magicString;
//implementation
-(NSString *)magicString{
    NSString *stringToReturn = // create string
    return stringToReturn;
}
// use it
NSString *magic = [testString magicString];

向自己发送消息
@implementation XYZPerson
-(void)sayHello{
  [self saySomething:@"Hello, world!"];
}
-(void)saySomething:(NSString *)greeting{
  NSLog(@"%@", greeting);
}
@end

向父类发消息
@interface XYZShoutingPerson : XYZPerson
@end
/////////////////////
@implementation XYZShoutingPerson
-(void)saySomething:(NSString *)greeting{
  NSString *uppercaseGreeting = [greeting uppercaseString];
  [super saySomething:uppercaseGreeting];
}
@end

动态创建对象
// NSObject提供一个类方法, id like (NSObject *)
+(id)alloc;
// 
-(id)init;
//=============== use it
NSObject *newObject = [[NSObject alloc] init];

// init可能返回一个和alloc不同的对象,因此最好嵌套使用alloc和init,不推荐如下使用
NSObjet *someObject = [NSObject alloc];
[someObject init];

初始化方法可以带参数
-(id)initWithInt:(int)value;
-(id)initWithLong:(long)value;
//------------------
NSNumber *magicNumber = [[NSNumber alloc] initWithInt:42];

类工厂方法提供了另一个选择
+(NSNumber *)numberWithInt:(int)value;
+(NSNumber *)numberWithLong:(long)value;
//------------------
NSNumber *magicNumber = [NSNumber numberWithInt:42];

使用new来代替
XYZObject *object = [XYZObject new];
// is effectively the same as:
XYZObject *object = [[XYZObject alloc] init];

通过字面量创建
NSString *someString = @"Hello, world!";
// is same as
NSString *someString = [NSString stringWithCString:"Hello, world!" encoding:NSUTF8StringEncoding];

//=======
NSNumber *myBOOL = @YES;
NSNumber *myFloat = @3.14f;
NSNumber *myInt = @42;
NSNumber *myLong = @42L;
NSNumber *myInt2 = @(84 / 2);

OBJC 是一个动态语言
// 下面代码会产生运行时错误,因为NSString没有removeAllObjects方法
id someObject = @"Hello, World!";
[someObject removeAllObjects];

// 下面代码会产生编译时错误
NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];

比较对象
// 因为是指针,所以可以这样比较是否同一个对象
if(firstPerson == secondPerson){
  
// the same object
}
// 如果要比较数据是否相同,使用isEqual
if([firstPerson isEqual:secondPerson]) {
  
// is identical to second
}

使用nil
// nil 是一个对象指针,声明一个对象指针无需初始化,编译器会初始化它为nil
XYZPerson *somePerson;
// ------------
if(somePerson != nil){
  
// ====
}
// or 
if(somePerson){
   
// ===
}

posted @ 2013-11-19 23:11 cuigang 阅读(137) | 评论 (0)编辑 收藏

用OBJC编程 0-简介 & .1 定义类

<Programming with Objective-C>-0-Introduction

OBJC是OSX和IOS的主要编程语言,它是C的超集,提供了面向对象的特性和动态运行时类型信息。OBJC继承了C的语法,基本数据类型和流程控制,附加了定义类和方法的语法。也为动态类型绑定提供了语言级别的支持。

<Programming with Objective-C>-1-Defining Classes

可变性决定值是否可以更改
一些类定义对象是immutable的,意味着对象的内容不可被其它对象改变。NSString和NSNumber是immutable的

一些immutable类页游mutable版本。比如NSString的NSMutableString。

尽管NSString和NSMutableString是不同的类,它们有非常多的相似之处

从另一个类继承
从另一个类继承,子类继承了父类所有的行为和属性。也可以定义自己的behavior和properties,或者override父类的behavior

NSMutableString继承于NSString,因此拥有所有NSString的功能,也增加了append,insert,replace,delete substring等方法

根类提供基本功能
如果你定义一个自己的类,应该至少继承于NSObject

类的接口定义

基本语法
1 @interface SimpleClass : NSObject
2 
3 @end

Properties控制访问一个对象的值
@interface Person : NSObject

@property NSString 
*firstName; // 对象用指针
@property NSString *lastName;
@property NSNumber 
*yearOfBirth;
@property 
int yearOfBirth_1; // 用基本类型

@end

Property属性指明数据的可访问性和存储情况
@interface Person : NSObject
@property (
readonly) NSString* firstName;
@property (
readonly) NSString* lastName;
@end

方法定义
-(void)someMethod;
前面的 - 号表示这是一个实例方法

方法可以带参数

-(void)someMethodWithValue:(SomeType)value;

可以有多个参数
-(void)someMethodWithFirstValue:(SomeType)value1 secondValue:(AnotherType)value2;
secondValue 是第二个参数签名的一部分

因此,下面的函数签名不同:
-(void)someMethodWithFirstValue:(SomeType)info1 anotherValue:(AnotherType)info2;
-(void)someMethodWithFirstValue:(SomeType)info1 secondValue:(YetAnotherType)onfo2;

类名称必须唯一
类名必须唯一,甚至和库或者框架里的类也不能重名,建议使用三个字符的前缀。
两个字母前缀,如NS,UI,已经被Apple保留

类的实现

基本语法

#import "XYZPerson.h"

@implementation XYZPerson

@end

实现方法

// interface like this
@interface XYZPerson : NSObject
- (void)sayHello;
@end

// implementation like this

@implementation XYZPerson
- (void)sayHello{
   NSLog(
@"Hello, World!");
}
@end

类也是一个对象

在OBJC里,类自己也是一个Class类型的对象。类类型不能通过声明的语法定义property,但是它可以接收消息。

类类型的方法的典型用途是工厂方法,用来进行对象的分配和初始化,如NSString的工厂方法

+(id)string;
+(id)stringWithString:(NSString *)aString;
+(id)stringWithFormat:(NSString *)format,.. . ;
+(id)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)end error:(NSError **)error;
+(id)stringWithCString:(const char*)cString encoding:(NSStringEncoding)enc;

+ 号表示这是一个类的方法

posted @ 2013-11-19 18:34 cuigang 阅读(441) | 评论 (0)编辑 收藏

2013年11月17日

UTF8 to Unicode

1 //unicode      bin                           utf8
2 0x0000~0x007f  0xxxxxxx                    0x00~0x7f
3 0x0080~0x07ff  110xxxxx 10xxxxxx           0xCx 0x8x ~ 0xDx 0xBx
4 0x0800~0xffff  1110xxxx 10xxxxxx 10xxxxxx  0xEx 0x8x 0x8x ~ 0xEx Bx Bx

posted @ 2013-11-17 10:31 cuigang 阅读(171) | 评论 (0)编辑 收藏