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

CG@CPPBLOG

/*=========================================*/
隨筆 - 76, 文章 - 39, 評論 - 137, 引用 - 0
數(shù)據(jù)加載中……

2013年11月23日

用OBJC編程 9 - Conventions

用OBJC編程 9 - Conventions

  • 有些名字在你的app里必須唯一
  • 類名必須唯一,因此請使用前綴,建議使用三個字母的前綴,避免和Cocoa框架沖突,類名使用名詞
  • 方法名不要前綴,以小寫字母開始,多個參數(shù)時,其它參數(shù)要有參數(shù)名。第一個單詞指明方法的效果,或者一個行為等等。
  • 如果方法參數(shù)包括error,它應該是最后一個參數(shù),如果參數(shù)包括一個block,它應該在最后,不應該有多個block參數(shù)。方法名長度要適中。
  • 避免縮寫
  • 分類里的方法名加上前綴,避免沖突。
  • 局部變量應該是唯一的。
  • 訪問器的名稱要符合慣例。否則在KVC時可能不能工作。
  • 工廠方法名應該以類名開始(或者父類的類名)

posted @ 2013-11-23 11:33 cuigang 閱讀(313) | 評論 (0)編輯 收藏

用OBJC編程 8 - Dealing with Errors

用OBJC編程 8 - Dealing with Errors

使用NSError,

委托方法會產(chǎn)生Error
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
NSError包括錯誤碼,錯誤業(yè)務領(lǐng)域domain和描述。為保證每個錯誤碼唯一,使用了domain,NSURLConnection的domain是NSURLErrorDomain

通過引用參數(shù)傳遞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發(fā)生錯誤,返回NO,并且更新anyError
// 如果你對error不感興趣,可以傳遞NULL

產(chǎn)生你自己的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 閱讀(385) | 評論 (0)編輯 收藏

2013年11月21日

用OBJC編程 7 - Working with Blocks

用OBJC編程 7 - Working with Blocks

Block 是語言級別的特性。它是一個OBJC的對象,可以被加入容器如NSArray或NSDictionary。它可以捕獲所處作用域的數(shù)值,非常類似其它語言的closure或者lambda。

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

可以像函數(shù)指針那樣聲明一個變量來持有這個block
void (^simpleBlock)(void);
simpleBlock = ^{
   NSLog(@"This is a block");
}; // 注意這里有一個分號

也可以這樣寫
void (^simpleBlock)(void= ^{
    NSLog(@"This is a block");
};

調(diào)用這個block
simpleBlock();

帶上參數(shù)和返回值
^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內(nèi)的值,一旦捕獲,這個值就不會變化,即便后續(xù)改變這個值
-(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;

通過參數(shù)傳遞Block,例如實現(xiàn)一個回調(diào)
-(IBAction)fetchRemoveInformation:(id)sender{
  [self showProgressIndicator];
  XYZWebTask *task = //,,,

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

// beginTaskWithCallbackBlock 的定義是這樣的

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

最佳實踐是將block作為最后一個參數(shù),這樣便于閱讀。

也可以使用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();

避免強引用循環(huán)
在block里捕獲self,諸如在一個callback block里,會引入內(nèi)存管理問題。block會會維護一個捕獲對象的強引用,包括self
@interface XYZBlockKeeper : NSObject
@property (copy) void (^block)(void);
@end
////////////////////////
@implementation XYZBlockKeeper
-(void)configureBlock{
  self.block = ^{
    [self doSomething];    // 捕獲了一個self的強引用
                           
// 建立了一個強引用循環(huán)
  }
}
@end

上述代碼會產(chǎn)生一個編譯警告,為了避免這種情況,最佳實踐是捕獲一個self的弱引用
-(void)configureBlock{
   XYZBlockKeeper * __weak weakSelf = self;
   self.block = ^ {
      [weakSelf doSomething];
   };
}

block可以簡化枚舉(略)
block可以簡化并發(fā)任務(略)



posted @ 2013-11-21 19:20 cuigang 閱讀(342) | 評論 (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位系統(tǒng)下是32位的,在64位下是64位的。通過API...  閱讀全文

posted @ 2013-11-21 17:34 cuigang 閱讀(369) | 評論 (0)編輯 收藏

用OBJC編程 5 - Working with Protocols

用OBJC編程 5 - Working with Protocols

協(xié)議定義了交互的消息
@protocol XYZPieChartViewDataSource
- (NSUInteger) numberOfSegments;
- (CGFloat)    sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
- (NSString *) titleForSegmentAtIndex:(NSUInteger)segmentIndex;
@end

數(shù)據(jù)源作為View的一個屬性,只要是符合協(xié)議的對象就可以,所以類型是id。
@interface XYZPieChartView : UIView
@property (weak) id <XYZPieChartViewDataSource> dataSource;
@end
委托和數(shù)據(jù)源屬性通常聲明為weak,以避免強引用循環(huán)。

設(shè)置屬性為一個不符合協(xié)議的對象,將會引起一個編譯時警告。

可選方法,使用@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

運行時檢查可選方法
如果一個方法是可選的,那么在調(diào)用前應該檢查它是否實現(xiàn)。
NSString *thisSegmentTitle; // Local object variables are automatically initialized to nil
if([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]){
    thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}

respondsToSelector: 方法用了一個selector,@selector。
如上定義一個符合協(xié)議的id類型,調(diào)用respondsToSelector,會產(chǎn)生一個編譯時錯誤,解決方案是聲明對象符合NSObject協(xié)議

從協(xié)議繼承
最佳實踐是,你的協(xié)議依從NSObject協(xié)議。NSObject對象依從NSObject協(xié)議。
一旦你的協(xié)議依從NSObject協(xié)議,那么依從你協(xié)議的任何對象都必須實現(xiàn)NSObject協(xié)議的方法,但因為它們應該是NSObject的子類,你就不必自己實現(xiàn)這些NSObject的方法。依從NSObject協(xié)議非常有用。
@protocol MyProtocol <NSObject>

@end

comform 一個協(xié)議
@interface MyClass : NSObject <MyProtocol, AnotherProtocol>

@end
如果一個類聲明了大量的協(xié)議,意味著代碼需要重構(gòu)成多個小的類。

一旦聲明依從某個協(xié)議,就必須實現(xiàn)所有的required方法,和需要的optional方法,否則編譯器會給出警告。方法的簽名必須相同。

Cocoa 和 Cocoa Touch 定義了大量的protocol
  • view的數(shù)據(jù)源協(xié)議
  • view的委托協(xié)議delegate
  • 一些類似的類,但是無繼承關(guān)系,比如NSArray和NSDictionary依從NSCoding協(xié)議
  • 一些OBJC語言級特性,也依賴協(xié)議,如一個容器需要依從NSFastEnumeration協(xié)議才能使用快速枚舉fast enumeration;copy的屬性依從NSCopying協(xié)議,否則會得到一個運行時異常。

為匿名使用協(xié)議

有時候,一個框架的開發(fā)者為了向使用者隱藏一個類,只把它的接口通過協(xié)議暴露

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 閱讀(363) | 評論 (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 的新增方法可能會導致名字沖突,在運行時可能會出現(xiàn)未知的行為,為了避免這種情況,需要增加前綴
@interface NSSortDescriptor (XYZAdditions)
+ (id)xyz_sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending;
@end
//  ------ use it -------
NSSortDescriptor *descriptor = [NSSortDescriptor xyz_sortDescriptorWithKey:@"name" ascending:YES];

類擴展類似分類,但只能用于編譯時有源碼情況,并且必須寫在實現(xiàn)文件里,因此不能通過這個為框架類擴展。擴展語法類似分類
@interface ClassName ()
{
    id _someCustomInstanceVariable;
}
@property NSObject *extraProperty;
@end
也叫匿名分類。不像分類那樣,擴展可以增加屬性和實例變量。編譯器會自動synthesize accessor方法。如果你增加方法,必須實現(xiàn)在主要的@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屬性的行為,編譯器都會產(chǎn)生錯誤,但是可以通過動態(tài)運行時特性避免編譯器錯誤,諸如調(diào)用NSObject的performSelector方法。

如果你打算構(gòu)建私有方法或?qū)傩裕憧梢月暶饕粋€分離的頭文件來聲明擴展,諸如XYZPerson.h和XYZPersonPrivate.h

分類和擴展并不是定制一個類的唯一途徑,也不是最好方法,要考慮可否使用子類化或者委托的方法來實現(xiàn)。


posted @ 2013-11-20 18:55 cuigang 閱讀(297) | 評論 (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"];

大多數(shù)屬性有一個實例變量。
缺省的讀寫屬性會由編譯器自動生成一個實例變量,以下劃線開始,如_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;

如果你并不想提供數(shù)值給其它對象,你不必聲明一個屬性而使用一個實例變量
@interface SomeClass: NSObject{
  NSString *_myNonPropertyInstanceVariable;
}
@end

@implementation SomeClass{
  NSString *_anotherCustomInstanceVariable;
}

在初始化方法里訪問實例變量
Setter方法會有附加效果。它們可能觸發(fā)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屬性實現(xiàn)了getter和setter,或者為readonly實現(xiàn)了getter。編譯器認為你想控制屬性實現(xiàn),也不會再為你自動生成一個實例變量。因此,如果你仍然需要一個實例變量,你需要手動synthesize
@synthesize property = _property;

屬性缺省是原子性的。atomic
@interface XYZObject : NSObject
@property NSObject *implicitAtomObject;                  // 缺省是atomic
@property (atomic) NSObject *explicitAtomicObject;       // 指明atomic
@end
缺省訪問器已經(jīng)解決了多線程并發(fā)的問題。

如果你定制了一個atomic, readwrite的屬性的setter,而讓編譯器自動生成getter,將會得到一個編譯時警告。

你可以聲明nonatomic屬性,因為不需要guarantee,處理并發(fā),因此它的訪問器比atomic屬性更快。

屬性的原子性并不意味著對象是線程安全的。例如firstName和LastName。

管理對象的生命周期,對象是通過指針來訪問,內(nèi)存是動態(tài)申請的,指針變量的生命周期不代表對象的證明周期。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,因此你可能會持有一個懸掛指針,指向一個未知內(nèi)存,向它發(fā)消息可能會導致崩潰。

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”,不會發(fā)生變化

一個被聲明為copy的對象必須支持NSCopying協(xié)議。如果你要直接set一個copy屬性的實例變量,例如在初始化方法里,一定要設(shè)置原始對象的copy
-(id)initWithSomeOriginalString:(NSString *)aString{
  self = [super init];
  
if(self){
     _instanceVariableForCopyProperty = [aString copy];
  }
  
return self;
}


posted @ 2013-11-20 16:49 cuigang 閱讀(293) | 評論 (0)編輯 收藏

2013年11月19日

用OBJC編程 2 - working with Objects

用OBJC編程 2 - working with Objects

發(fā)送和接收消息
@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.
}

通過參數(shù)傳遞對象
-(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];

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

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

動態(tài)創(chuàng)建對象
// 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];

初始化方法可以帶參數(shù)
-(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];

通過字面量創(chuàng)建
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 是一個動態(tài)語言
// 下面代碼會產(chǎn)生運行時錯誤,因為NSString沒有removeAllObjects方法
id someObject = @"Hello, World!";
[someObject removeAllObjects];

// 下面代碼會產(chǎn)生編譯時錯誤
NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];

比較對象
// 因為是指針,所以可以這樣比較是否同一個對象
if(firstPerson == secondPerson){
  
// the same object
}
// 如果要比較數(shù)據(jù)是否相同,使用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 閱讀(276) | 評論 (0)編輯 收藏

用OBJC編程 0-簡介 & .1 定義類

<Programming with Objective-C>-0-Introduction

OBJC是OSX和IOS的主要編程語言,它是C的超集,提供了面向?qū)ο蟮奶匦院蛣討B(tài)運行時類型信息。OBJC繼承了C的語法,基本數(shù)據(jù)類型和流程控制,附加了定義類和方法的語法。也為動態(tài)類型綁定提供了語言級別的支持。

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

可變性決定值是否可以更改
一些類定義對象是immutable的,意味著對象的內(nèi)容不可被其它對象改變。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屬性指明數(shù)據(jù)的可訪問性和存儲情況
@interface Person : NSObject
@property (
readonly) NSString* firstName;
@property (
readonly) NSString* lastName;
@end

方法定義
-(void)someMethod;
前面的 - 號表示這是一個實例方法

方法可以帶參數(shù)

-(void)someMethodWithValue:(SomeType)value;

可以有多個參數(shù)
-(void)someMethodWithFirstValue:(SomeType)value1 secondValue:(AnotherType)value2;
secondValue 是第二個參數(shù)簽名的一部分

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

類名稱必須唯一
類名必須唯一,甚至和庫或者框架里的類也不能重名,建議使用三個字符的前綴。
兩個字母前綴,如NS,UI,已經(jīng)被Apple保留

類的實現(xiàn)

基本語法

#import "XYZPerson.h"

@implementation XYZPerson

@end

實現(xiàn)方法

// 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 閱讀(666) | 評論 (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 閱讀(316) | 評論 (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>
            亚洲国产精品毛片| 美女视频黄 久久| 日韩视频在线观看国产| 蜜臀a∨国产成人精品| 久久偷窥视频| 欧美一区二区三区在线| 亚洲国产mv| 国产精品拍天天在线| 久久理论片午夜琪琪电影网| 一区二区三区偷拍| 一本色道88久久加勒比精品| 亚洲精品网站在线播放gif| 亚洲三级网站| 欧美激情一区| 欧美阿v一级看视频| 亚洲视频综合在线| 夜夜狂射影院欧美极品| 午夜精彩国产免费不卡不顿大片| 国产精品成人一区二区网站软件 | 欧美va天堂va视频va在线| 亚洲大片av| 久久一区二区三区四区| 91久久久久久久久| 亚洲福利国产精品| 国产一区二区精品在线观看| 欧美色视频一区| 欧美日韩精品久久久| 欧美日韩国产探花| 国产精品乱码久久久久久| 国产精品国产三级国产aⅴ浪潮| av成人免费在线观看| 最新中文字幕亚洲| 亚洲第一视频| 亚洲精品久久久蜜桃| 久久高清福利视频| 欧美激情va永久在线播放| 亚洲高清123| 亚洲少妇最新在线视频| 亚洲视频电影在线| 久久午夜av| 蜜臀av在线播放一区二区三区| 久久精品一本| 国产精品99久久久久久人| 亚洲欧美在线另类| 欧美日韩国产在线播放网站| 国产欧美在线观看一区| 亚洲电影第1页| 欧美1区2区3区| 久久爱www久久做| 久久人人爽人人爽爽久久| 久久伊人精品天天| 国内精品久久久久久久影视麻豆| 米奇777超碰欧美日韩亚洲| 亚洲看片一区| 国产精品www色诱视频| 久久久久综合| 亚洲一区免费观看| 午夜免费在线观看精品视频| 久久久久久一区二区| 亚洲国产乱码最新视频| 国产精品草莓在线免费观看| 一区二区三区国产精华| 99热这里只有精品8| 国产精品色在线| 久久精品国产在热久久| 亚洲欧美日韩中文视频| 国产精品高清网站| 亚洲在线一区| 欧美专区亚洲专区| 在线一区二区三区四区| 国产日韩欧美二区| 亚洲精品一区二区在线| 国内精品久久久久久 | 女人天堂亚洲aⅴ在线观看| 欧美一激情一区二区三区| 日韩视频一区| 99天天综合性| 欧美日本在线一区| 亚洲国产精品久久| 最新亚洲电影| 国内伊人久久久久久网站视频 | 久久成人18免费观看| 欧美一区二区三区免费在线看 | 国产性做久久久久久| 国产精品爽爽爽| 国产欧美日韩一区二区三区在线观看 | 亚洲欧美在线观看| 欧美性淫爽ww久久久久无| 欧美日韩国产成人在线| 亚洲国产日韩一区| 亚洲激情专区| 免费不卡欧美自拍视频| 欧美一区免费视频| 国产美女精品免费电影| 亚洲欧美国产精品va在线观看| 欧美一区在线看| 91久久综合| 国产精品久久久久久久久免费樱桃| 亚洲美女视频| 亚洲欧美激情四射在线日| 国产精品美女www爽爽爽| 久久综合色8888| 亚洲欧美日韩在线一区| 亚洲成人在线视频播放 | 久久人91精品久久久久久不卡| 一区二区三欧美| 国产农村妇女精品一二区| 久久久av网站| 亚洲欧美激情视频| 米奇777超碰欧美日韩亚洲| 国产精品mm| 欧美一区永久视频免费观看| 亚洲日本成人网| 一区二区三区中文在线观看| 久久精品视频在线免费观看| 免费在线观看一区二区| 亚洲在线黄色| 亚洲天堂黄色| 亚洲视频一区二区在线观看 | 欧美三级在线视频| 亚洲在线网站| 欧美a级理论片| 裸体素人女欧美日韩| 欧美专区在线播放| 性欧美video另类hd性玩具| 99热在线精品观看| 久久亚洲精品一区| 亚洲综合国产| 美女日韩欧美| 国产一区香蕉久久| 国产精品久久精品日日| 久久久天天操| 欧美插天视频在线播放| 欧美在线高清视频| 亚洲国产高清一区| 国产综合欧美| 激情小说另类小说亚洲欧美| 一区二区久久久久久| 亚洲在线一区二区三区| 午夜日韩在线| 美国成人直播| 一区二区三区在线不卡| 香蕉久久夜色精品| 亚洲欧美日韩中文视频| 亚洲影视在线播放| 欧美在线地址| 欧美日韩天堂| 欧美大片在线观看一区| 亚洲日韩欧美视频一区| 亚洲精品自在在线观看| 亚洲女性裸体视频| 老司机久久99久久精品播放免费| 欧美日韩中文字幕综合视频| 亚洲国产精品久久精品怡红院| 久久久久综合网| av成人国产| 欧美日韩在线免费观看| 亚洲成色www8888| 亚洲视频在线免费观看| 亚洲高清不卡av| 欧美成人午夜剧场免费观看| 亚洲美洲欧洲综合国产一区| 久久国产手机看片| 欧美韩日一区二区三区| 日韩天堂av| 欧美午夜不卡| 一卡二卡3卡四卡高清精品视频| 欧美日韩精品一区二区三区四区| 国产日韩精品一区观看| 久久精品视频网| 欧美va天堂在线| 亚洲国产一区二区a毛片| 欧美一区二区三区啪啪| 国产精品一区久久| 在线观看成人网| 欧美激情一区二区三区在线视频| 一区二区三区视频在线播放| 欧美日韩视频在线一区二区| 一区二区免费看| 欧美自拍偷拍| 亚洲网在线观看| 在线日韩中文字幕| 免费黄网站欧美| 欧美片在线播放| 欧美自拍偷拍午夜视频| 久久久久88色偷偷免费| 一区二区欧美亚洲| 另类欧美日韩国产在线| 免费在线日韩av| 欧美午夜在线视频| 欧美中文在线视频| 国产精品国产福利国产秒拍| 久久日韩精品| 亚洲国产高清一区| 欧美专区在线| 性色av一区二区三区| 欧美绝品在线观看成人午夜影视| 欧美va天堂在线| 亚洲三级免费电影| 久久精品人人|