• <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
            數據加載中……

            用OBJC編程 6 - Value and Collections

            用OBJC編程 6 - Value and Collections

            OBJC里可以用基本的C原生類型,也定義了一些擴展的原生類型。
            BOOL類型,它的值是YES和NO,YES等于true等于1。NO等于false等于0。
            Cocoa定義了特殊的原生類型,如NSInteger和CGFloat。像NSInteger和NSUInteger,依賴于平臺,在32位系統下是32位的,在64位下是64位的。
            通過API傳遞時,最佳實踐是使用這些特定平臺的類型。而局部變量如循環計數,使用基本C變量更好。

            C結構體可持有原生類型
            一些Cocoa API用C結構體持有數值
            NSString *mainString = @"This is a long string";
            NSRange substringRange = [mainString rangeOfString:@"long"];
            NSRange結構體持有location和length,本例中,substringRange為{10,4}。
            類似的在Quartz中,基于CGFloat,NSPoint和NSSize(OSX)或者CGPoint和CGSize(IOS)都是C結構體。

            用對象來代替原生類型

            例如NSString,NSString是不可變的,這意味著你需要一個不同的字符串時,你需要創建一個新的對象。NSMutableString是可變的,是NSString的子類。
            NSString *firstString = [[NSString alloc] initWithCString:"Hello World" encoding:NSUTF8StringEncoding];
            NSString *secondString = [NSString stringWithCString:"Hello World" encoding:NSUTF8StringEncoding];
            NSString *thirdString = @"Hello World";

            // ------------
            NSString *name = @"John";
            name = [name stringByAppendingString:@"ny"]; // returns a new string object

            //----------------
            NSMutableString *name = [NSMutableString stringWithString:@"John"];
            [name appendString:@"ny"]; // same object, but now represents "Johnny"

            格式化字符串
            NSString *magicString = [NSString stringWithFormat:@"The magic number is %i", magicNumber];

            NSNumber可以表示任何基本C標量類型,包括,char, double, float, int, long, short, 以及unsigned類型和BOOL。
            NSNumber* magicNumber     = [[NSNumber alloc] initWithInt:42];
            NSNumber* unsignedNumber  = [[NSNumber alloc] initWithUnsignedInt:42u];
            NSNumber* longNumber      = [[NSNumber alloc] initWithLong:42l];
            NSNumber* boolNumber      = [[NSNumber alloc] initWithBOOL:YES];

            NSNumber* simpleFloat  = [NSNumber numberWithFloat:3.14f];
            NSNumber* betterDouble = [NSNumber numberWithDouble:3.1415926535];

            NSNumber* someChar = [NSNumber numberWithChar:'T'];

            可以使用字面常量來創建NSNumber實例,這些例子等價于使用NSNumber的工廠方法
            NSNumber *magicNumber = @42;
            NSNumber *unsignedNumber = @42u;
            NSNumber *longNumber = @42l;
            NSNumber *boolNumber = @YES;
            NSNumber *simpleFloat = @3.14f;
            NSNumber *betterDouble = @3.1415926535;
            NSNumber *someChar = @'T';

            可以使用訪問器獲得標量值
            int scalarMagic = [magicNumber intValue];
            unsigned int scalarUnsigned = [unsignedNumber unsignedIntValue];
            BOOL scalarBool = [boolNumber boolValue];

            NSNumber也可以用在NSInteger和NSUInteger上面
            NSInteger anInteger = 64;
            NSUInteger anUnsignedInteger = 100;

            NSNumber *firstInteger = [[NSNumber alloc] initWithInteger:anInteger];
            NSNumber *sencondInteger = [NSNumber numberWithUnsignedInteger:anUnsignedIneger];

            NSInteger integerCheck = [firstInteger integerValue];
            NSUInteger unsignedCheck = [sencondInteger unsignedIntegerValue];

            NSNumber實例是不可變的,而且沒有可變版本的子類,如果你需要一個不同的數字,就使用另一個NSNumber實例。NSNumber實際是一個類簇class cluster。

            使用NSValue,NSValue是NSNumber的父類,可以用來持有更多的類型,包括指針和結構等。它有非常多的工廠方法。
            NSString *mainString = @"This is a long string";
            NSRange substringRange = [mainString rangeOfString:@"long"];
            NSValue *rangeValue = [NSValue valueWithRange:substringRange];

            // ---------
            typedef struct{
                
            int i;
                
            float f;
            } MyIntegerFloatStruct;

            //======================
            stuct MyIntegerFloatStruct aStruct;
            aStruct.i = 42;
            aStruct.f = 3.14;

            NSValue *structValue = [NSValue value:&aStruct withObjCType:@encode(MyIntegerFloatStruct)];

            Collections 容器
            像NSArray,NSSet和NSDictionary這些容器可以管理一組OBJC 對象實例,如果你要放一個標量進去,需要包裝為NSNumber或者NSValue。這些容器使用強引用持有它們的內容,也就意味著這些對象實例和容器生命周期一樣。
            基本的NSArray,NSSet和NSDictionary都是不可變的,它們都有一個可變版本的子類。

            NSArray是有序的容器,它的內容不必是同一類對象。它有很多不同的初始化方法和工廠方法,依賴于對象的數目:
            + (id)arrayWithObject:(id)anObject;
            + (id)arrayWithObjects:(id)firstObject, ,,,;
            + (id)initWithObjects: (id)firstObject, ,,,;

            可變參數版本的如arrayWithObjects依賴nil終止
            NSArray *someArray = [NSArray arrayWithObjects:someObject, someString, someNumber, nil];

            如果某個列表中的對象是nil,可能會發生意外的截斷
            id firstObject = @"SomeString";
            id secondObject = nil;
            id thirdObject = @"anotherString";
            NSArray *someArray = [NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil];

            使用字面常量
            NSArray *someArray = @[firstObject, secondObject, thirdObject];

            // 列表里不能有nil,nil是一個非法數值,會導致運行時異常
            id firstObject = @"someString";
            id secondObject = nil;
            NSArray *someArray = @[firstObject, secondObject];
            // exception: "attempt to insert nil object"
            如果你需要在容器中使用nil,你應該使用NSNull單件。

            查詢Array
            NSUInteger numberOfItems = [someArray count];
            if([someArray containsObject:someString]){
              
            //,,,
            }
            ///// -------------
            if([someArray count] > 0){ // 訪問無效index將導致運行時異常
                NSLog(@"First item is: %@", [someArray objectAtIndex:0]);
            }
            //// ------ 可以使用下標語法
            if([someArray count] > 0){
                NSLog(@"First item is: %@", someArray[0]);
            }

            Array排序
            因為NSArray是不可變的,像排序這樣的方法會產生一個新的array
            NSArray *unsortedStrings = @[@"gammaString"@"alphaString"@"betaString"];
            NSArray *sortedStrings = [unsortedStrings sortedArrayUsingSelector:@Selector(compare:)];

            可變版本
            NSMutableArray *mutableArray = [NSMutableArray array];
            [mutableArray addObject:@"gamma"];
            [mutableArray addObject:@"alpha"];
            [mutableArray addObject:@"beta"];

            [mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"];

            [mutableArray sortUsingSelector:@selector(caseInseneitiveCompare:)];

            NSSet是一個無序的容器,同樣是不可變的,也有可變版本。初始化同樣是nil結尾。Set只為一個對象存儲一個引用,哪怕你多次加入一個對象
            NSNumber *number = @42;
            NSSet *numberSet = [NSSet setWithObjects:number, number, number, nil];
            // numberSet里僅僅有一個對象

            字典是一個key-value容器,注意需要一個對象作為key,這個key對象需要依從NSCopying協議

            創建字典,
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                      someObject, @"anObject",
                
            @"Hello, World1"@"helloString",
                             @42@"magicNumber",
                       someValue, @"aValue",
                                 nil];

            使用字面常量
            // 注意和上面是反的
            NSDictionary 
            *dictionary = @{
                      @"anObject", someObject,
                   @"helloString", @"Hello, World1",
                   @"magicNumber", @42,
                        @"aValue", someValue,,
                                 }; // 沒有nil

            查詢字典
            NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];
            // or
            NSNumber *storedNumber = dictionary[@"magicNumber"];

            用NSNull代替nil,NSNull是一個單件,可以用等號來判斷
            NSArray *array = @[@"string", @42, [NSNull null] ];

            for(id object in array){
                
            if(object == [NSNull null]){
                    NSLog(@"Found a null object");
               }
            }

            使用容器保存你的對象。NSArray和NSdictionary可以很容易把內容寫入磁盤。如果它包含的內容是一個property list對象(NSArray,NSDictionary, NSString,NSData,NSDate和NSNumber ), 則可以從磁盤中重新創建。
            NSURL *fileURL = //,,,
            NSArray *array = @[@"first"@"second"@"third"];

            BOOL success = [array writeToURL:fileURL atomically:YES];
            if(!success){
                
            // an error occured ,,,
            }

            //,,,,,,,,,,,,,,
            NSURL *fileURL = //,,,
            NSArray *array = [NSArray arrayWithContentsOfURL:fileURL];
            if(!array){
                
            // an error occured ,,,
            }
            如果是其它對象,你需要一個歸檔對象,諸如NSKeyedArchiver,去創建一個容器的歸檔。創建歸檔僅僅需要每一個對象實現NSCoding協議,這意味著每一個對象能夠知道如何在一個歸檔文件里編碼自己(通過實現encodeWithCoder方法)以及如何解碼(實現initWithCoder方法)。

            NSArray, NSSet, and NSDictionary 以及它們的可變版本都支持NSCoding,這意味著你可以歸檔一個復雜的對象關系。Interface Builder就是這么做的。

            快速枚舉,包括NSArray,NSSet,NSDictionary這樣支持NSFastEnumeration協議的容器都支持OBJC語言級別的快速枚舉
            for(id eachObject in array){
              NSLog(@"Object: %@", eachObject);
            }

            for(NSString *eachKey in dictionary){
              id object = dictionary[eachKey];
              NSLog(@"Object: %@ for key: %@"object, eachKey);
            }

            對于有序容器,你需要自己保存索引。不能在快速枚舉里改變容器,即使容器是可變的,否則將得到一個運行時異常。
            int index = 0;
            for(id eachObject in array){
              NSLog(@"Object at index %i is: %@", index, eachObject);
              index++;
            }

            枚舉對象,使用NSEnumerator對象
            for(id eachObject in [array reverseObjectEnumerator]){ // 反序枚舉
             
            //,,,
            }

            id eachObject;
            while( (eachObject = [enumerator nextObject]) ) { // 中止時,nextObject返回nil
                NSLog(@"Current object is: %@", eachObject);
            }
            // 在條件語句里使用=號,會產生一個編譯時警告,因此使用了雙括號來消除這個警告











            posted on 2013-11-21 17:34 cuigang 閱讀(349) 評論(0)  編輯 收藏 引用 所屬分類: OBJC

            青青草国产成人久久91网| 久久久久国产日韩精品网站| 国产亚洲成人久久| 久久精品夜夜夜夜夜久久| 无码人妻久久一区二区三区蜜桃 | 欧美粉嫩小泬久久久久久久 | 伊人久久大香线蕉AV一区二区| 99久久精品国产一区二区三区| 久久综合久久久| 久久亚洲国产精品一区二区| 97久久精品无码一区二区| 久久国产精品99久久久久久老狼| 久久国产精品成人影院| 久久精品亚洲一区二区三区浴池| 亚洲AV无码久久精品狠狠爱浪潮| 久久天天躁狠狠躁夜夜avapp| 精品乱码久久久久久久| 亚洲精品高清久久| 久久久久久国产精品无码下载 | 思思久久99热只有频精品66| 久久人人爽人人爽人人av东京热 | 久久婷婷五月综合色99啪ak| 久久亚洲精品无码VA大香大香| 亚洲AV日韩精品久久久久久| 97久久精品无码一区二区| 精品久久久久久久中文字幕| 亚洲人成无码久久电影网站| 久久亚洲精精品中文字幕| 久久99国产精品成人欧美| 久久99热这里只频精品6| 精品综合久久久久久888蜜芽| 久久精品成人免费观看97| 精品久久久久久国产| 久久九九有精品国产23百花影院| 久久久久国产精品三级网| 久久精品亚洲日本波多野结衣 | 久久亚洲日韩精品一区二区三区| 热99re久久国超精品首页| 中文字幕无码免费久久| 爱做久久久久久| 亚洲精品无码久久久久去q |