青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

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 閱讀(309) | 評論 (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 閱讀(383) | 評論 (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 閱讀(339) | 評論 (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 閱讀(365) | 評論 (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 閱讀(353) | 評論 (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 閱讀(293) | 評論 (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 閱讀(288) | 評論 (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 閱讀(273) | 評論 (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 閱讀(661) | 評論 (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 閱讀(312) | 評論 (0)編輯 收藏

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区亚洲一区| 国产精品久久久久久久免费软件 | 欧美一级大片在线观看| 国产精品日韩在线观看| 欧美一级播放| 久久久久久久一区二区| 亚洲黄一区二区| 亚洲老司机av| 国产精品女主播在线观看| 久久久久se| 女主播福利一区| 午夜欧美精品久久久久久久| 欧美在线视频一区二区| 亚洲欧洲另类| 亚洲一区二区伦理| 在线免费观看日本欧美| 91久久精品美女| 国产精品久久婷婷六月丁香| 老司机一区二区三区| 欧美极品影院| 欧美一区二区三区精品| 国产精品久久久久久久久婷婷| 亚洲国产婷婷香蕉久久久久久99| 亚洲日本成人| 国产一区二区三区的电影 | 亚洲欧洲视频在线| 亚洲无线视频| 亚洲黄色成人网| 一区二区三区视频观看| 亚洲电影免费观看高清| 亚洲视频免费在线| 亚洲美女网站| 久久久91精品| 欧美一区二区精品| 欧美另类一区| 欧美顶级大胆免费视频| 国产日韩欧美一区二区三区在线观看 | 午夜精品久久久久久久久久久久久 | 欧美一区二区三区视频| 一本大道久久a久久综合婷婷| 欧美亚洲综合久久| 亚洲永久网站| 欧美精品v国产精品v日韩精品| 久久亚洲综合色一区二区三区| 国产精品露脸自拍| 日韩午夜在线观看视频| 亚洲精品国偷自产在线99热| 久久精品一区二区三区中文字幕 | 久久av老司机精品网站导航| 欧美日韩在线观看一区二区三区| 欧美jizzhd精品欧美巨大免费| 国产区亚洲区欧美区| 一本综合精品| 亚洲一区二区三区色| 欧美日韩精品一区二区三区| 欧美国产专区| 亚洲国产日韩欧美在线99| 久久久99爱| 欧美不卡在线视频| 亚洲国产成人91精品| 久久久久久久激情视频| 久久―日本道色综合久久| 国产欧美亚洲精品| 小处雏高清一区二区三区| 欧美在线观看日本一区| 国产精品jizz在线观看美国| 亚洲美女av在线播放| 在线一区二区三区四区| 欧美三级资源在线| 中文av一区二区| 欧美在线影院| 激情文学综合丁香| 久久亚洲国产成人| 亚洲第一中文字幕| 夜夜嗨av一区二区三区中文字幕| 亚洲精选中文字幕| 亚洲欧美成人在线| 好看的日韩视频| 欧美大片18| 一区二区三区高清不卡| 欧美一区二区黄| 欲色影视综合吧| 欧美精品激情在线| 亚洲一区二区三区成人在线视频精品| 午夜免费在线观看精品视频| 国产一区自拍视频| 欧美肥婆在线| 午夜激情久久久| 免费亚洲电影在线观看| 亚洲麻豆视频| 国产精品一卡二| 久久久www成人免费无遮挡大片| 亚洲国产日韩欧美在线图片| 99在线热播精品免费99热| 国产精品亚洲综合久久| 久久综合一区二区| 亚洲网站在线观看| 裸体歌舞表演一区二区| 亚洲午夜极品| 在线观看日韩www视频免费| 欧美日韩在线播| 久久精品国产免费观看| 亚洲久久成人| 久久青青草综合| 亚洲愉拍自拍另类高清精品| 伊人天天综合| 国产精品免费一区二区三区在线观看| 久久婷婷一区| 午夜日本精品| 一本大道久久a久久精二百| 欧美gay视频| 欧美中文在线视频| 亚洲午夜视频在线| 91久久一区二区| 国产一区深夜福利| 国产精品一区在线观看你懂的| 免费在线观看精品| 久久久久久久网| 欧美一区二区三区视频在线观看| 亚洲精选成人| 亚洲高清精品中出| 久久青青草综合| 欧美在线在线| 欧美一区二区视频观看视频| 亚洲影音先锋| 一区二区三区久久精品| 亚洲精品日本| 91久久夜色精品国产网站| 伊人久久婷婷| 在线欧美日韩国产| 国产主播在线一区| 韩国成人福利片在线播放| 国产九九精品| 国产伦精品免费视频| 国产精品入口福利| 国产精品综合网站| 国产欧美韩国高清| 国产日产亚洲精品系列| 国产日韩一区二区三区在线播放| 国产精品久久久久久久久免费樱桃| 欧美日韩美女| 欧美午夜在线观看| 国产精品高潮呻吟| 国产老女人精品毛片久久| 国产精品毛片| 国产一区二区成人| 国产亚洲欧洲997久久综合| 国产专区精品视频| 在线激情影院一区| 日韩视频一区| 午夜久久一区| 久久久精品免费视频| 噜噜噜91成人网| 宅男在线国产精品| 羞羞答答国产精品www一本| 性做久久久久久久久| 亚洲精品一区二| 日韩视频在线观看| 国产精品手机视频| 免费成人在线观看视频| 亚洲三级电影全部在线观看高清| 有坂深雪在线一区| 亚洲人成网站在线观看播放| 99国产精品久久久久老师| 亚洲综合精品自拍| 久久久久青草大香线综合精品| 能在线观看的日韩av| 亚洲九九爱视频| 性做久久久久久| 欧美成人嫩草网站| 国产精品美女一区二区在线观看| 国内成人自拍视频| 日韩视频精品| 久久久久国色av免费看影院| 亚洲福利免费| 亚洲在线成人精品| 美女露胸一区二区三区| 国产精品视频一区二区三区| 精品999日本| 亚洲制服av| 免费黄网站欧美| 亚洲一区二区在| 午夜国产不卡在线观看视频| 夜夜嗨av一区二区三区免费区| 欧美一级久久久| 亚洲高清资源| 欧美一区二区三区在线免费观看| 欧美国产免费| 狠狠色丁香久久婷婷综合_中| 一区二区精品国产| 久久性天堂网| 亚洲欧美日韩一区二区| 欧美日韩精品免费看| 激情一区二区三区| 亚洲综合欧美日韩| 亚洲黄色av| 欧美大片在线影院| 在线观看亚洲专区| 久久久久久久久久久久久女国产乱 | 久久婷婷综合激情|