Objective-C tips
11615 ワード
Objective-C tips
nil
次の2つのOC文法は等価です.
文字列オブジェクトを作成:
インスタンス変数set&get方法
ヘッダファイルにインスタンス変数を宣言し、ANDROIDにおけるインスタンス変数はmで始まり、OCにおけるインスタンス変数は
親の種類を書き換える方法は、サブクラスの実現ファイルに書き換えるだけで、ヘッダファイルには声明が不要です.書き換えられた方法はすでに親タイプのヘッダファイルによって宣言されています.
Initializers
コンストラクタ、クラスのデフォルトはinitの初期化方法だけで、カスタマイズした初期化方法を追加できます.
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.
Objective-Cでは、同じ配列は任意のタイプのオブジェクトを含むことができるが、Objective-Cのオブジェクトでなければならず、基本タイプとC structではない.
各オブジェクトには、
Exception
クラス名プレフィックス
OCにはパッケージや名前空間の概念がない(これは本当に酔っている)ので、OCのクラス名にはプレフィックスがあります.会社名の略語やプロジェクト名の略語としてもいいです.通常は3文字を使います.二つの文字はアップルに使われています.ネーミングの衝突を防ぐためです.NS--NeXTSTEP、アップルが買収した会社です.
Strong and Weak References
両方のオブジェクトが相手を引用して強い引用をしているとメモリが漏れます.弱引きでこの問題を解決することができます.通常は2つのオブジェクトが互いに相手を引用する場合、この2つのオブジェクトは親子関係があります.親オブジェクトは子オブジェクトを強く引用します.子オブジェクトは親オブジェクトを弱く引用するだけです.
以前の各宣言の例示的変数は、対応するset get方法を書く必要があります.Prpertyを通じて宣言します.set get方法を書かなくてもいいです.コンパイラはインスタンス変数とset getアクセス方法を声明してくれます.
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(この二つの単語は面白いので、属性に訳せます.)
いつ
上の二番目の言葉はどう分かりますか?たくさんのthat…
カスタムset get方法
あなたのset get方法に論理がある場合、クラス実現ファイルにカスタムset get方法を追加する必要があります.
本稿は『iOS Prograamming The Big Nerd Ranch Guide 4 th Edition』の第二、第三章をまとめたものである.
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 ojectBecause 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 ArayObjective-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』の第二、第三章をまとめたものである.