Objective-C tips

11615 ワード

Objective-C tips
nil
次の2つのOC文法は等価です.
if (venue == nil) {
    [organizer remindToFindVenueForParty];
}
if (!venue) {  //  JS   ,         
    [organizer remindToFindVenueForParty];
}
他の言語はしばしば空でないと判断されます.JAVA JSのように空の指針に異常がないように、OCの中で次のように判断する必要はありません.対象がnilであれば、OCは呼び出された方法を直接無視します.
// Is venue non-nil?
if (venue) { //  JS,       
    [venue sendConfirmation];
}
@
文字列オブジェクトを作成:
NSString *myString = @"Hello, World!";
NSLogフォーマット文字列は、異なる種類の異なるプレースホルダを使用します.
int a = 1;
float b = 2.5;
char c = 'A';
NSLog(@"Integer: %d Float: %f Char: %c", a, b, c);

        
NSString *str = @"hello oc";
NSLog(@"print %@", str);
%@は、「a pointer to any oject」を表し、オブジェクトがLogされると、オブジェクトdescriptionにメッセージを送り、文字列に戻る.javaのtoStringのような方法です.
インスタンス変数set&get方法
ヘッダファイルにインスタンス変数を宣言し、ANDROIDにおけるインスタンス変数はmで始まり、OCにおけるインスタンス変数は_で始まり、約束は必須ではない.get方法はgetで始まる必要がない.
#import 

@interface BKItem : NSObject
{
    NSString *_itemName; //*         
    NSString *_serialNumber;
    int _valueInDollars;
    NSDate *_dateCreated;
}

//       set get  ,  java          
- (void)setItemName:(NSString *)str;
- (NSString *)itemName;

- (void)setSerialNumber:(NSString *)str;
- (NSString *)serialNumber;

- (void)setValueInDollars:(int)v;
- (int)valueInDollars;

- (NSDate *)dateCreated; //  get  

@end
クラスの実現においてset get方法を実現する:
#import "BKItem.h"

@implementation BKItem

- (void)setItemName:(NSString *)str
{
    _itemName = str;
}
- (NSString *)itemName
{
    return _itemName;
}

- (void)setSerialNumber:(NSString *)str
{
    _serialNumber = str;
}
- (NSString *)serialNumber
{
    return _serialNumber;
}

- (void)setValueInDollars:(int)v
{
    _valueInDollars = v;
}
- (int)valueInDollars
{
    return _valueInDollars;
}

- (NSDate *)dateCreated
{
    return _dateCreated;
}

@end

set getの二つのアクセス文法は、ポイント文法を使うと最終的にコンパイラによって第一の方法に変換されますが、点文法を使うほうが便利です.
        BKItem *item = [[BKItem alloc] init];
        [item setItemName:@"Red Sofa"];
        [item setSerialNumber:@"A1B2C"];
        [item setValueInDollars:100];
        
        NSLog(@"%@ %@ %@ %d", [item itemName], [item dateCreated],
              [item serialNumber], [item valueInDollars]);
        
       //            dot syntax:      set  ,      get  
        item.itemName=@"Red Sofa";
        item.serialNumber=@"A1B2C";
        item.valueInDollars = 100;
        NSLog(@"%@ %@ %@ %d", item.itemName, item.dateCreated,
              item.serialNumber, item.valueInDollars);
書き換え方法
親の種類を書き換える方法は、サブクラスの実現ファイルに書き換えるだけで、ヘッダファイルには声明が不要です.書き換えられた方法はすでに親タイプのヘッダファイルによって宣言されています.
Initializers
コンストラクタ、クラスのデフォルトはinitの初期化方法だけで、カスタマイズした初期化方法を追加できます.
#import 

@interface BKItem : NSObject
{
    NSString *_itemName; //*         
    NSString *_serialNumber;
    int _valueInDollars;
    NSDate *_dateCreated;
}

//            
- (instancetype)initWithItemName:(NSString *)name valueInDollars:(int) value serialNumber:(NSString *)sNumber;
- (instancetype)initWithItemName:(NSString *)name;

@end
ヘッダファイルにおいて宣言された初期化方法を実装し、通常のパラメータが最も多い初期化方法は、初期化方法を指定するinstancetypeのキーワードが初期化方法の復帰タイプであり、初期化方法を呼び出す人はinstancetypeである.
#import "BKItem.h"

@implementation BKItem

// Designated initializer (      ,          init  )
- (instancetype)initWithItemName:(NSString *)name valueInDollars:(int) value serialNumber:(NSString *)sNumber{
    // Call the superclass's designated initializer
    self = [super init];
    // Did the superclass's designated initializer succeed?
    if (self) { //       ,  JS  
        // Give the instance variables initial values
        _itemName = name;
        _serialNumber = sNumber;
        _valueInDollars = value;
        // Set _dateCreated to the current date and time
        _dateCreated = [[NSDate alloc] init];
    }
    // Return the address of the newly initialized object
    return self;
}
- (instancetype)initWithItemName:(NSString *)name{
    return [self initWithItemName:name
                   valueInDollars:0
                     serialNumber:@""];
}

//      init  ,     designated initializer
- (instancetype)init
{
    return [self initWithItemName:@"Item"];
}

//      description  
- (NSString *)description
{
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, recorded on %@",
     self.itemName,
     self.serialNumber,
     self.valueInDollars,
     self.dateCreated];
    return descriptionString;
}

@end
id-a pointer to any oject
Because id is defined as「a pointer to any oject」、you do not include an*when decleang avarable or method parameter of this type.
IDを使って変数を宣言する時、彼はもう指針になっていますので、*号を追加する必要はありません.
Class method類方法(静的方法)
クラスの方法は、対象のインスタンスを作成するためによく使われる(JAVAでの単一のインスタンスのオブジェクトを取得する方法と同様に)、またはグローバル属性を取得するために使用される.クラスメソッドはインスタンス変数にアクセスできません.クラス方法は+号によって宣言される.
最初の文書の中で文の種類の方法を宣言して、頭のファイルの内容の順序に注意します:instance variable、class method、initializer、instance method.
#import 

@interface BKItem : NSObject
{
    NSString *_itemName; //*         
    NSString *_serialNumber;
    int _valueInDollars;
    NSDate *_dateCreated;
}

+ (instancetype)randomItem; //   

- (instancetype)initWithItemName:(NSString *)name valueInDollars:(int) value serialNumber:(NSString *)sNumber;
- (instancetype)initWithItemName:(NSString *)name;

@end
実現ファイルでクラス方法を実現します.
#import "BKItem.h"

@implementation BKItem

+ (instancetype)randomItem
{
    // Create an immutable array of three adjectives
    NSArray *randomAdjectiveList = @[@"Fluffy", @"Rusty", @"Shiny"];
    // Create an immutable array of three nouns
    NSArray *randomNounList = @[@"Bear", @"Spork", @"Mac"];
    // Get the index of a random adjective/noun from the lists
    // Note: The % operator, called the modulo operator, gives
    // you the remainder. So adjectiveIndex is a random number
    // from 0 to 2 inclusive.
    NSInteger adjectiveIndex = arc4random() % [randomAdjectiveList count];
    NSInteger nounIndex = arc4random() % [randomNounList count];
    // Note that NSInteger is not an object, but a type definition
    // for "long"
    NSString *randomName = [NSString stringWithFormat:@"%@ %@",
                            [randomAdjectiveList objectAtIndex:adjectiveIndex],
                            [randomNounList objectAtIndex:nounIndex]];
    int randomValue = arc4random() % 100;
    NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
                                    '0' + arc4random() % 10,
                                    'A' + arc4random() % 26,
                                    '0' + arc4random() % 10,
                                    'A' + arc4random() % 26,
                                    '0' + arc4random() % 10];
    BKItem *newItem = [[self alloc] initWithItemName:randomName
                                       valueInDollars:randomValue
                                         serialNumber:randomSerialNumber];
    return newItem;
}

@end
NSAray NSMutable Aray
Objective-Cでは、同じ配列は任意のタイプのオブジェクトを含むことができるが、Objective-Cのオブジェクトでなければならず、基本タイプとC structではない.nilを配列に追加することはできませんが、NSNullは可能です.
NSMutableArray *items = [[NSMutableArray alloc] init];
[items addObject:nil]; //ERROR -[__NSArrayM insertObject:atIndex:]: object cannot be nil
[items addObject:[NSNull null]]; // this is OK
アレイの下付きアクセス、以下の2つの方法は等価です.
NSString *str = [items objectAtIndex:0];
NSString *rts = items[0];
isa instance variable
各オブジェクトには、isaのインスタンス変数ポインタがあり、オブジェクトの属するクラスを指します.
Exception
 // id         ,  JAVA  Object
id lastObj = [items lastObject];
[lastObj count];
lastObjにcount方法がない場合、以下のエラーが発生します.
2015-07-07 19:31:16.787 RandomItems[3647:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BKItem count]: unrecognized selector sent to instance 0x7fd1a2c0c650'
unrecognized selector、selectorはmessageで、クラスの中の方法です.-[BKItem count]、-receiverがBKItemの例であることを表し、+であればreceiverはBKItem classである.
クラス名プレフィックス
OCにはパッケージや名前空間の概念がない(これは本当に酔っている)ので、OCのクラス名にはプレフィックスがあります.会社名の略語やプロジェクト名の略語としてもいいです.通常は3文字を使います.二つの文字はアップルに使われています.ネーミングの衝突を防ぐためです.NS--NeXTSTEP、アップルが買収した会社です.
Strong and Weak References
両方のオブジェクトが相手を引用して強い引用をしているとメモリが漏れます.弱引きでこの問題を解決することができます.通常は2つのオブジェクトが互いに相手を引用する場合、この2つのオブジェクトは親子関係があります.親オブジェクトは子オブジェクトを強く引用します.子オブジェクトは親オブジェクトを弱く引用するだけです.
//         
__weak BNRItem *_container;
@property
以前の各宣言の例示的変数は、対応するset get方法を書く必要があります.Prpertyを通じて宣言します.set get方法を書かなくてもいいです.コンパイラはインスタンス変数とset getアクセス方法を声明してくれます.
@property NSString *itemName;
下の表は@propertyを使うかどうかの違いです.
file
Without properties
With properties
BNRThing.h
@interface BNRThing:NSObject{NSString*_name]-(void)set Name:(NSString*)n;(NSString*)name;@end
@interface BNRThing:NSObject@propertyNSString*name;@end
BNRThing.m
@implemenation BNRThing-(void)setName:(NSString*)n{runame=n;}-(NSString*)name{return name}@end
@implement ationBNRThing@end
注意property属性名にはアンダースコアプレフィックスは必要ありません.
property atribute(この二つの単語は面白いので、属性に訳せます.)
@property (nonatomic, readwrite, strong) NSString *itemName;
nonatomic, atomicは、デフォルト値はatomicであり、マルチスレッドに関連するアトリブテ(原子、すなわちスレッドが安全である.非原子、すなわち非スレッドセキュリティであり、より性能が高い)であり、iOSでは一般的にnonatomicを使用する.readwrite, readonly、標準値はreadwriteで、コンパイラがset方法を生成するかどうかを教え、読み取り専用がset方法を生成しない.strong, weak, copy, unsafe_unretainedは、OCの対象に対して、そのデフォルト値はstrongである.基本タイプのようなOCではないオブジェクトであれば、オプション値unsafe-unretainedだけでなく、OCではないオブジェクトのデフォルト値でもあるので、ステートメントは不要です.
いつcopyを使いますか?宣言する変数の種類に可変のサブクラスがある場合、NSString/NSMutable String or NSAray/NSMutable Arayのように、copyを用いて生成される最終コードは、以下のようにオブジェクトをコピーし、変数をコピーして生成されたオブジェクトに強力に参照する.
- (void)setItemName:(NSString *)itemName
{
    _itemName = [itemName copy];
}
@property (nonatomic, strong) BNRItem *containedItem;
@property (nonatomic, weak) BNRItem *container;
@property (nonatomic, copy) NSString *itemName;
@property (nonatomic, copy) NSString *serialNumber;
@property (nonatomic) int valueInDollars;
@property (nonatomic, readonly, strong) NSDate *dateCreated;
The memory management atribute’s values are strong、weak、copy、and unsafe_unretained.This atribute describes the type of reference that the object with the instance variable has to the object the variable is pointing to.
上の二番目の言葉はどう分かりますか?たくさんのthat…
カスタムset get方法
あなたのset get方法に論理がある場合、クラス実現ファイルにカスタムset get方法を追加する必要があります.
- (void)setContainedItem:(BNRItem *)containedItem
{
    _containedItem = containedItem;
    self.containedItem.container = self;
}
set get方法を同時に実現するなら、インスタンス変数をヘッダファイルに宣言する必要があります.@propertyはインスタンス変数を自動的に追加しません.
本稿は『iOS Prograamming The Big Nerd Ranch Guide 4 th Edition』の第二、第三章をまとめたものである.