66

Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

Embed Size (px)

Citation preview

Page 1: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 2: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 3: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

紙版は絶版、電⼦書籍は販売中

Page 4: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 6: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 7: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 8: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 9: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 10: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSInteger integerValue = 10; double doubleValue = 128.9;

// 明示キャスト NSUInteger value1 = (NSUInteger)integerValue; NSInteger value2 = (NSInteger)doubleValue; char value3 = (char)integerValue; double value4 = (double)integerValue;

Page 11: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSInteger integerValue = 10; double doubleValue = 128.9;

// 暗黙キャスト NSUInteger value1 = integerValue; NSInteger value2 = doubleValue; char value3 = integerValue; double value4 = integerValue;

Page 12: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSInteger integerValue = -8000000000000002345; double doubleValue = 123456789.935;

// 誤差が出るキャスト NSInteger value1 = doubleValue; // 123456789 double value2 = integerValue; // -8000000000000002048 NSUInteger value3 = integerValue; // 10446744073709549271u short value4 = doubleValue; // -13035

Page 13: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

doubleValue + floatValue // double floatValue + doubleValue // double doubleValue + longDoubleValue // long double intValue + floatValue // float intValue + charValue // int intValue + longValue // long charValue + shortValue // int

Page 14: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

1 / 3.0 // 0.3333333333333333 1 / 3.0f // 0.33333333f 1 / 3 // 0

1 / 3.0 == 1 / 3 // false 1 / 3.0 == 1 / 3.0f // false

Page 15: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

int a = 1, b = 3, c = 5, d = 4; // 明示キャストによる制御 c * (a / b * d) // 0 c * (a / (double)b * d) // 6.666666666666666 c * (int)(a / (double)b * d) // 5 (int)(c * ((double)a / b * d)) // 6 c * (double)(a / b) * d // 0

Page 16: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

short shortValue = 0x7FFF; long longValue = 0x12345678;

// 再解釈キャスト short value1 = *(short*)&longValue; // 0x5678 long value2 = *(long*)&shortValue; // 0x6080000000207FFF double value3 = *(double*)&longValue; // 1.508974781700064e-315

Page 17: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSData *data = [[NSMutableData alloc] init];

// アップキャスト NSObject *obj1 = (NSObject*)data;

// ダウンキャスト NSMutableData *obj2 = (NSMutableData*)data;

Page 18: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSData *data = [[NSMutableData alloc] init];

// アップキャスト NSObject *obj1 = data;

// ダウンキャストは明記が必要 NSMutableData *obj2 = (NSMutableData*)data;

Page 19: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

NSString *obj = [[NSString alloc] init];

// 無関係な型へのキャスト NSNumber *number = (NSNumber*)obj;

// メソッドが存在しなければ実行時エラー NSString *text = [number descriptionWithLocale: nil];

Page 20: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

id object;

// 可能性の判定 if ([object isKindOfClass:[NSNumber class]]) { // 整合性が約束されればキャストを実施 NSNumber *number = (NSNumber*)object; }

Page 21: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 22: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 23: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 24: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 25: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let integerValue: Int = 65 let doubleValue: Double = 128.9

// 型を変換 let value1 = UInt(integerValue) let value2 = Int(doubleValue) let value3 = UnicodeScalar(integerValue) let value4 = Double(integerValue)

Page 26: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let sourceValue: UInt = 18446744073709551615

// 変換できないとき let value1 = Int(sourceValue)

let value2 = Int("120x") // nillet value3 = try MyValue(sourceValue) // Error

Page 27: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let source: UInt = 18446744073709551000

// 型を変換 let value1 = Int(bitPattern: source) // -616 let value2 = Int8(truncatingBitPattern:source) // -104

Page 28: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let source: Int64 = 0x12345678

// 再解釈 var value1 = unsafeBitCast(source, Double.self) // 1.508974781700064e-315

var value2 = unsafeBitCast(source, Int32.self)

Page 29: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

as as? as!

let instance: NSData = NSMutableData()

// アップキャスト let object1 = instance as NSObject

// ダウンキャスト let object2 = instance as? NSMutableData let object2 = instance as! NSMutableData

Page 30: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let instance: NSData = NSMutableData()

// アップキャスト let object1: NSObject = instance

// ダウンキャスト let object2 = instance as? NSMutableData let object2 = instance as! NSMutableData

Page 31: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let object = NSString()

// 無関係な型へのキャスト let number1 = object as? NSData // nil

let number2 = object as! NSData // ERROR

Page 32: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 33: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 34: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 35: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 36: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

(int)value Int(value)

[instance toDouble] Double(instance)

(SubClass*)object (BaseClass*)object

object as? SubClass object as BaseClass

[object isKindOfClass: [SomeClass class]]

if let obj = object as? SomeClass {

*(double*)&value unsafeBitCast(

value, Double.self)

Page 37: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 38: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 39: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 40: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

@interface ESMyObject : NSObject

// NSInteger 型から自分の型に変換する - (instancetype)initWithInteger:(NSInteger)value;

@end

Page 41: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

@interface ESMyObject : NSObject

// 自分自身から NSInteger に変換 - (NSInteger)toInteger;

@end

Page 42: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// NSInteger から自分自身に変換 ESMyObject *object = [[ESMyObject alloc] initWithInteger: 10]; // 自分自身を NSInteger に変換 NSInteger value = [object toInteger];

Page 43: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

@interface ESMyObject : NSObject

// NSLocale からの変換? - (instancetype)initWithLocale:(NSLocale)locale;

// 自分自身から NSPoint への変換? - (NSPoint)toPoint;

@end

Page 44: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 45: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 46: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

struct MyValue { // Int 型から自身の型へ変換するイニシャライザ init(_ value: Int) { } }

Page 47: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

extension Int { // MyValue 型から自身の型 (Int) へ変換する init(_ value: MyValue) {

} }

Page 48: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// Int から自分自身に変換 let value = MyValue(100) // 自分自身を Int に変換 let number = Int(value)

Page 49: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

struct MyValue { // ラベル名を伴う場合は Full-Width 変換ではない init(locale: NSLocale) {…} // これがもし Full-Width 変換なら // NSPointに変換イニシャライザとして実装したい func toPoint() -> NSPoint {…} }

Page 50: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 51: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 52: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

init / init?init … throws

Page 53: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 54: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 55: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// 一般に Optional Binding とセットで使う if let number = instance as? NSData {

} else {

// キャストできなかった場合も想定できる }

Page 56: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// 確実にダウンキャスト出来る時にだけ使う let data = instance as! NSData

// キャストできない場合は強制終了 let data = instance as! NSNumber

Page 57: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// 確実にダウンキャスト出来るかを判定 if instance is NSData {

// ここならキャストが確実にできる let data = instance as! NSData

}

Page 58: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 59: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let workData = NSMutableData()

// 継承関係より NSData で扱えるのは明らか let data = workData as NSData

Page 60: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

// 中身的には NSMutableData 型でも、 let instance: AnyObject = NSMutableData()

// 外見からは NSData にキャスト出来るか分からない// こういうときは as? または as! でのキャストが必要 let data = instance as? NSData

Page 61: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

let string = String()

// ブリッジ機構は Swift 標準ライブラリが提供 let objcString = string as NSString

Page 62: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 63: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 64: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift

(SubClass*)instance instance as? SubClass

(SubClass*)instance instance as! SubClass

(BaseClass*)instance instance as BaseClass

(BaseClass*)instance instance as? BaseClass

(SomeClass*)instance instance as SomeClass

isKindOfClass: conformsToProtocol: instance is SomeType

Page 65: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift
Page 66: Objective-C のキャストと Swift の型変換を比べてみる #akibaswift