• <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>

            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 閱讀(291) | 評論 (0)編輯 收藏

            用OBJC編程 8 - Dealing with Errors

            用OBJC編程 8 - Dealing with Errors

            使用NSError,

            委托方法會產(chǎn)生Error
            -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
            NSError包括錯誤碼,錯誤業(yè)務領域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 閱讀(359) | 評論 (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 閱讀(322) | 評論 (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 閱讀(348) | 評論 (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)。

            設置屬性為一個不符合協(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
            • 一些類似的類,但是無繼承關系,比如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 閱讀(331) | 評論 (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 閱讀(273) | 評論 (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屬性的實例變量,例如在初始化方法里,一定要設置原始對象的copy
            -(id)initWithSomeOriginalString:(NSString *)aString{
              self = [super init];
              
            if(self){
                 _instanceVariableForCopyProperty = [aString copy];
              }
              
            return self;
            }


            posted @ 2013-11-20 16:49 cuigang 閱讀(269) | 評論 (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 閱讀(252) | 評論 (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 閱讀(640) | 評論 (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 閱讀(294) | 評論 (0)編輯 收藏

            久久精品国产亚洲麻豆| 亚洲AV日韩精品久久久久久久| 久久精品嫩草影院| 99精品伊人久久久大香线蕉| 99久久亚洲综合精品成人| 久久精品一区二区影院| 国内精品九九久久精品| 国产成人久久激情91| 99久久精品免费看国产免费| 欧美日韩精品久久久久| 久久99精品国产| 日本久久久久久久久久| 久久精品国产亚洲AV嫖农村妇女| 国产精品va久久久久久久| 久久久噜噜噜久久中文字幕色伊伊 | 精品一二三区久久aaa片| 久久91亚洲人成电影网站| 久久乐国产精品亚洲综合| 性欧美丰满熟妇XXXX性久久久| 99久久综合狠狠综合久久止| 四虎影视久久久免费观看| 人妻无码久久一区二区三区免费| 国产精品99久久久久久猫咪 | 国产精品久久久久天天影视| 很黄很污的网站久久mimi色| 午夜精品久久久久久99热| 国产精品免费久久久久影院| 亚洲va久久久噜噜噜久久| 欧美国产精品久久高清| 国产一区二区精品久久 | 色综合久久天天综合| 久久久久久久波多野结衣高潮| 国产成人精品综合久久久| 久久久久久久97| 久久久精品国产免大香伊| 久久九九免费高清视频| 久久精品国内一区二区三区| 日韩精品久久久久久免费| 国产精品久久久香蕉| 欧美色综合久久久久久 | 久久久久人妻精品一区二区三区 |