рдЕрдзрд┐рдХрд╛рдВрд╢ iOS рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдпрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВред рд╕реНрд╡рд┐рдлреНрдЯ рдПрдХ рдмреЗрд╣рддрд░реАрди рднрд╛рд╖рд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде iOS рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХрд╛ рднрд╡рд┐рд╖реНрдп рдирд┐рд╣рд┐рдд рд╣реИред рд▓реЗрдХрд┐рди рднрд╛рд╖рд╛ рдФрдВрдзрд╛ рд░реВрдк рд╕реЗ рдЯреВрд▓рдХрд┐рдЯ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реА рд╣реБрдИ рд╣реИ, рдФрд░ рд╕реНрд╡рд┐рдлреНрдЯ рдЯреВрд▓рдХрд┐рдЯ рдореЗрдВ рдЦрд╛рдорд┐рдпрд╛рдВ рд╣реИрдВред
рд╕реНрд╡рд┐рдлреНрдЯ рдХрдВрдкрд╛рдЗрд▓рд░ рдореЗрдВ рдЕрднреА рднреА рдХреАрдбрд╝реЗ рд╣реИрдВ рдЬреЛ рдЗрд╕реЗ рдЧрд▓рдд рдХреЛрдб рдмрдирд╛рдиреЗ рдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддреЗ рд╣реИрдВред рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рд╕реНрдерд┐рд░ ABI рдирд╣реАрдВ рд╣реИред рдФрд░, рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рд╕реНрд╡рд┐рдлреНрдЯ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдмрд╣реБрдд рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЪрд▓ рд░рд╣реА рд╣реИрдВред
рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ, рдореМрдЬреВрджрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдкрд░ рд╡рд┐рдХрд╛рд╕ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд▓рд╛рднрджрд╛рдпрдХ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рд╡рд╣ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдпрд╣ рд╣реБрдЖ рдХрд░рддрд╛ рдерд╛!
рд▓реЗрдЦреЛрдВ рдХреА рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ, рд╣рдо рдЖрдкрдХреЛ рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдХреА рдЙрдкрдпреЛрдЧреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдФрд░ рд╕реБрдзрд╛рд░реЛрдВ рдХреЛ рджрд┐рдЦрд╛рдПрдВрдЧреЗ, рдЬреЛ рд▓реЗрдЦрди рдХреЛрдб рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдЦрдж рдмрдирд╛рддрд╛ рд╣реИред рд╣рд░ рдХреЛрдИ рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ рд▓рд┐рдЦрддрд╛ рд╣реИ рд╡рд╣ рдЕрдкрдиреЗ рд▓рд┐рдП рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдкрд╛рдПрдВрдЧреЗред

let
рдФрд░ var
рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдХреЛ рдЕрдм рдЪрд░ рдкреНрд░рдХрд╛рд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ: Xcode 8 рдореЗрдВ, __auto_type
рднрд╛рд╖рд╛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдФрд░ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ Xcode 8 рдкреНрд░рдХрд╛рд░ рдХрд╛ __auto_type
рдЙрджреНрджреЗрд╢реНрдп-C ++ (C ++ 0X рдХреЗ рдЖрдЧрдорди рдХреЗ рд╕рд╛рде auto
рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдерд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, let
рдФрд░ var
macros рдЬреЛрдбрд╝реЗрдВ:
#define let __auto_type const #define var __auto_type
рдпрджрд┐ рдЖрдк рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдХреНрд▓рд╛рд╕ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░ рдХреЗ рдмрд╛рдж const
рд▓рд┐рдЦрддреЗ рдереЗ, рддреЛ рдпрд╣ рдПрдХ рдЕрд╕рдВрдЧрдд рд▓рдЧреНрдЬрд░реА рдерд╛, рд▓реЗрдХрд┐рди рдЕрдм рдХреЙрдиреНрд╕ рдХреЗ рдирд┐рд╣рд┐рдд рдШреЛрд╖рдгрд╛ ( let
рдорд╛рдзреНрдпрдо let
) рдХреЛ рдордВрдЬреВрд░реА рджреЗ рджреА рдЧрдИ рд╣реИред рдЕрдВрддрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдЬрдм рдПрдХ рдмреНрд▓реЙрдХ рдХреЛ рдПрдХ рдЪрд░ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЕрдкрдиреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд╕рднреА рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП let
рдФрд░ var
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдо рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬрдм рдПрдХ рдЪрд░ nil
рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
- (nullable JMSomeResult *)doSomething { var result = (JMSomeResult *)nil; if (...) { result = ...; } return result; }
рдПрдХрдорд╛рддреНрд░ рдЕрдкрд╡рд╛рдж рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреЛрдб рд╢рд╛рдЦрд╛ рдореЗрдВ рдПрдХ рдЪрд░ рдХреЛ рдПрдХ рдорд╛рди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
NSString *value; if (...) { if (...) { value = ...; } else { value = ...; } } else { value = ...; }
рдпрджрд┐ рд╣рдо рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдХреЛ рдорд╛рди рджреЗрдирд╛ рднреВрд▓ рдЬрд╛рддреЗ рд╣реИрдВ рддреЛ рдХреЗрд╡рд▓ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣рдореЗрдВ рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рдЪреЗрддрд╛рд╡рдиреА рдорд┐рд▓реЗрдЧреАред
рдФрд░ рдЕрдВрдд рдореЗрдВ: рдЯрд╛рдЗрдк id
рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рд▓рд┐рдП let
рдФрд░ -Wno-auto-var-id
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ auto-var-id
рдЪреЗрддрд╛рд╡рдиреА (рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ "рдЕрдиреНрдп рдЪреЗрддрд╛рд╡рдиреА рдлреНрд▓реИрдЧ" рдореЗрдВ -Wno-auto-var-id
рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред
рдСрдЯреЛ рдмреНрд▓реЙрдХ рдкреНрд░рдХрд╛рд░ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп
рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдмреНрд▓реЙрдХ рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ:
let block = ^{ return @"abc"; };
рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдЖрдк ReactiveObjC рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХрдИ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИрдВ рдЬрд┐рдирдХреЗ рддрд╣рдд рдЖрдкрдХреЛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдпрджрд┐ рдХрд┐рд╕реА рдмреНрд▓реЙрдХ рдореЗрдВ рдХрдИ return
рд╣реИрдВ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
let block1 = ^NSUInteger(NSUInteger value){ if (value > 0) { return value; } else {
рдпрджрд┐ рдмреНрд▓реЙрдХ рдореЗрдВ return
рд╣реИ рдЬреЛ nil
рд▓реМрдЯрд╛рддрд╛ рд╣реИред
let block1 = ^NSString * _Nullable(){ return nil; }; let block2 = ^NSString * _Nullable(BOOL flag) { if (flag) { return @"abc"; } else { return nil; } };
рдпрджрд┐ рдмреНрд▓реЙрдХ рдХреЛ BOOL
рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
let predicate = ^BOOL(NSInteger lhs, NSInteger rhs){ return lhs > rhs; };
C (рдФрд░ рдЗрд╕рд▓рд┐рдП Objective-C) рдореЗрдВ рддреБрд▓рдирд╛ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рдЯрд╛рдЗрдк int
ред рдЗрд╕рд▓рд┐рдП, рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ BOOL
рдХреЛ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдирд┐рдпрдо рдмрдирд╛рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред
рдкреАрдврд╝реА рдФрд░ for...in
рдПрдХреНрд╕рдХреЛрдб 7 рдореЗрдВ, рдЬреЗрдирд░рд┐рдХ (рдпрд╛ рдмрд▓реНрдХрд┐, рд╣рд▓реНрдХреЗ рдЬреЗрдирд░рд┐рдХ) рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдПред рд╣рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдЖрдк WWDC рд╕рддреНрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЗрд╕реЗ рдпрд╣рд╛рдБ рдпрд╛ рдпрд╣рд╛рдБ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ ред
рдЕрдкрдиреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЬреЗрдиреЗрд░рд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдо рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд╡рд╣ id
( NSArray<id> *
) рд╣реЛред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╡рд┐рд░рд╛рд╕рдд рдХреЛрдб рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдЕрднреА рддрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИрдВред
let
рдФрд░ var
рдореИрдХреНрд░реЛ рдХреЗ рд╕рд╛рде, рд╣рдо рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ for...in
: рд▓реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
let items = (NSArray<NSString *> *)@[@"a", @"b", @"c"]; for (let item in items) { NSLog(@"%@", item); }
рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХреЛрдб рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, __auto_type
рдореЗрдВ for...in
рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ __auto_type
, рдХреНрдпреЛрдВрдХрд┐ for...in
рдХреЗрд╡рд▓ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреЛ NSFastEnumeration
рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЬреЗрдирд░рд┐рдХ рдХрд╛ рдХреЛрдИ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИред
рдЗрд╕ рдЦрд╛рдореА рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреЗ foreach
рдореИрдХреНрд░реЛ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдкрд╣рд▓реА рдмрд╛рдд рдЬреЛ рдзреНрдпрд╛рди рдореЗрдВ рдЖрддреА рд╣реИ: рдлрд╛рдЙрдВрдбреЗрд╢рди рдХреЗ рд╕рднреА рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдПрдХ objectEnumerator
рд╕рдВрдкрддреНрддрд┐ рд╣реЛрддреА рд╣реИ, рдФрд░ рдореИрдХреНрд░реЛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
#define foreach(object_, collection_) \ for (typeof([(collection_).objectEnumerator nextObject]) object_ in (collection_))
рд▓реЗрдХрд┐рди NSMapTable
рдФрд░ NSMapTable
рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдкрджреНрдзрддрд┐ рдХреБрдВрдЬрд┐рдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рдорд╛рдиреЛрдВ рдкрд░ рдирд╣реАрдВ (рдЖрдкрдХреЛ keyEnumerator
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, objectEnumerator
рдирд╣реАрдВ)ред
рд╣рдореЗрдВ рдПрдХ рдирдИ рд╕рдВрдкрддреНрддрд┐ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ typeof
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
@interface NSArray<__covariant ObjectType> (ForeachSupport) @property (nonatomic, strong, readonly) ObjectType jm_enumeratedType; @end @interface NSDictionary<__covariant KeyType, __covariant ObjectType> (ForeachSupport) @property (nonatomic, strong, readonly) KeyType jm_enumeratedType; @end #define foreach(object_, collection_) \ for (typeof((collection_).jm_enumeratedType) object_ in (collection_))
рдЕрдм рд╣рдорд╛рд░рд╛ рдХреЛрдб рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИ:
Xcode рдХреЗ рд▓рд┐рдП рд╕реНрдирд┐рдкреЗрдЯ foreach (<#object#>, <#collection#>) { <#statements#> }
mutableCopy
рдФрд░ copy
/ mutableCopy
рдПрдХ рдЕрдиреНрдп рд╕реНрдерд╛рди рдЬрд╣рд╛рдВ рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╕реА-рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ, -mutableCopy
рдФрд░ -mutableCopy
(рд╕рд╛рде рд╣реА -copyWithZone:
рдФрд░ -mutableCopyWithZone:
рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╕реАрдзреЗ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ)ред
рд╕реНрдкрд╖реНрдЯ рдЬрд╛рддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, NSArray
рдХреЗ рд▓рд┐рдП, рдШреЛрд╖рдгрд╛рдПрдБ рд╣реЛрдВрдЧреА:
@interface NSArray<__covariant ObjectType> (TypedCopying) - (NSArray<ObjectType> *)copy; - (NSMutableArray<ObjectType> *)mutableCopy; @end
let items = [NSMutableArray<NSString *> array];
warn_unused_result
рдЪреВрдБрдХрд┐ рд╣рдордиреЗ -copy рдФрд░ -mutableCopy
рдХреЛ рдлрд┐рд░ рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЧрд╛рд░рдВрдЯреА рджреЗрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, warn_unused_result
рдореЗрдВ warn_unused_result
рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИред
#define JM_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
@interface NSArray<__covariant ObjectType> (TypedCopying) - (NSArray<ObjectType> *)copy JM_WARN_UNUSED_RESULT; - (NSMutableArray<ObjectType> *)mutableCopy JM_WARN_UNUSED_RESULT; @end
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЗ рд▓рд┐рдП, рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛:
let items = @[@"a", @"b", @"c"]; [items mutableCopy];
overloadable
рдХреБрдЫ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреНрд▓реИрдВрдЧ рдЖрдкрдХреЛ рд╕реА рднрд╛рд╖рд╛ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдФрд░ рдЗрд╕рд▓рд┐рдП рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдореЗрдВ)ред overloadable
рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╛ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рдеред
рдЕрддрд┐рджреЗрдп рдХрд╛рд░реНрдп рдХреЗрд╡рд▓ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рднрд┐рдиреНрди рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
#define JM_OVERLOADABLE __attribute__((overloadable))
JM_OVERLOADABLE float JMCompare(float lhs, float rhs); JM_OVERLOADABLE float JMCompare(float lhs, float rhs, float accuracy); JM_OVERLOADABLE double JMCompare(double lhs, double rhs); JM_OVERLOADABLE double JMCompare(double lhs, double rhs, double accuracy);
рдмреЙрдХреНрд╕рд┐рдВрдЧ рдХреЗ рднрд╛рд╡
2012 рдореЗрдВ рд╡рд╛рдкрд╕ WWDC 413 рд╕рддреНрд░ рдореЗрдВ, Apple рдиреЗ NSNumber
, NSArray
рдФрд░ NSDictionary
Shadow рдХреЗ рд▓рд┐рдП рд╢рд╛рдмреНрджрд┐рдХ рд╢реБрд░реБрдЖрдд рдХреА, рд╕рд╛рде рд╣реА рд╕рд╛рде рдмреЙрдХреНрд╕рд┐рдВрдЧ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рднреА рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдПред рдЖрдк рдХреНрд▓реИрдВрдЧ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред
рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдмреВрд▓рд┐рдпрди рдорд╛рди рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓рдкреЗрдЯрддреА рд╣реИ, рдЖрдкрдХреЛ рдХреБрдЫ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
рдХреБрдЫ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐рдпрд╛рдБ рдФрд░ рдЧреБрдг рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ (рдЬреИрд╕реЗ +[NSValue valueWithCGPoint:]
рд╡рд┐рдзрд┐ рдФрд░ CGPointValue
рдЧреБрдг), рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИ!
рдФрд░ 2015 рдореЗрдВ, рдПрд▓реЗрдХреНрд╕ рдбреЗрдирд┐рд╕реЛрд╡ рдиреЗ рдХреНрд▓реИрдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЪ рдмрдирд╛рдпрд╛ , рдЬрд┐рд╕рд╕реЗ рдЖрдк NSValue
рдореЗрдВ рдХрд┐рд╕реА рднреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдмрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП objc_boxable
рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
#define JM_BOXABLE __attribute__((objc_boxable))
typedef struct JM_BOXABLE JMDimension { JMDimensionUnit unit; CGFloat value; } JMDimension;
рдФрд░ рд╣рдо рдЕрдкрдиреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП @(...)
рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
let dimension = (JMDimension){ ... }; let boxedValue = @(dimension);
рдЖрдкрдХреЛ рдЕрднреА рднреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд╛рдкрд╕ -[NSValue getValue:]
рдпрд╛ рд╢реНрд░реЗрдгреА рд╡рд┐рдзрд┐ред
CoreGraphics рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдореИрдХреНрд░реЛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, CG_BOXABLE
, рдФрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА CGPoint
, CGSize
, CGVector
рдФрд░ CGRect
рд▓рд┐рдП рд╕рдорд░реНрдерд┐рдд рд╣реИрдВред
рдЕрдиреНрдп рдЖрдо рддреМрд░ рдкрд░ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рджрдо рдкрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
typedef struct JM_BOXABLE _NSRange NSRange; typedef struct JM_BOXABLE CGAffineTransform CGAffineTransform; typedef struct JM_BOXABLE UIEdgeInsets UIEdgeInsets; typedef struct JM_BOXABLE NSDirectionalEdgeInsets NSDirectionalEdgeInsets; typedef struct JM_BOXABLE UIOffset UIOffset; typedef struct JM_BOXABLE CATransform3D CATransform3D;
рдпреМрдЧрд┐рдХ рд╢рд╛рдмреНрджрд┐рдХ
рдПрдХ рдЕрдиреНрдп рдЙрдкрдпреЛрдЧреА рднрд╛рд╖рд╛ рдирд┐рд░реНрдорд╛рдг рдпреМрдЧрд┐рдХ рд╢рд╛рдмреНрджрд┐рдХ рд╣реИ ред рдпреМрдЧрд┐рдХ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдЬреАрд╕реАрд╕реА рдореЗрдВ рдПрдХ рднрд╛рд╖рд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдФрд░ рдмрд╛рдж рдореЗрдВ рд╕реА 11 рдорд╛рдирдХ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ред
рдпрджрд┐ рдкрд╣рд▓реЗ, UIEdgeInsetsMake
рдХреЛ рдХреЙрд▓ рдорд┐рд▓рд╛, рддреЛ рд╣рдо рдХреЗрд╡рд▓ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдорд┐рд▓реЗрдЧрд╛ (рд╣рдореЗрдВ UIEdgeInsetsMake
рдлрд╝рдВрдХреНрд╢рди рдХреА рдШреЛрд╖рдгрд╛ рдХреЛ рджреЗрдЦрдирд╛ рдерд╛), рдлрд┐рд░ рдХрдВрдкрд╛рдЙрдВрдб рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рд╕рд╛рде рдХреЛрдб рдЦреБрдж рдХреЗ рд▓рд┐рдП рдмреЛрд▓рддрд╛ рд╣реИ:
рдЦреЗрддреЛрдВ рдореЗрдВ рд╕реЗ рдХреБрдЫ рд╢реВрдиреНрдп рд╣реЛрдиреЗ рдкрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ:
(CGPoint){ .y = 10 }
рдмреЗрд╢рдХ, рдпреМрдЧрд┐рдХ рд╢рд╛рдмреНрджрд┐рдХ рдореЗрдВ рдЖрдк рди рдХреЗрд╡рд▓ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рднрд╛рд╡:
textFrame = (CGRect){ .origin = { .y = CGRectGetMaxY(buttonFrame) + textMarginTop }, .size = textSize };
Xcode рдХреЗ рд▓рд┐рдП рд╕реНрдирд┐рдкреЗрдЯреНрд╕ (NSRange){ .location = <#location#>, .length = <#length#> } (CGPoint){ .x = <#x#>, .y = <#y#> } (CGSize){ .width = <#width#>, .height = <#height#> } (CGRect){ .origin = { .x = <#x#>, .y = <#y#> }, .size = { .width = <#width#>, .height = <#height#> } } (UIEdgeInsets){ .top = <#top#>, .left = <#left#>, .bottom = <#bottom#>, .right = <#right#> } (NSDirectionalEdgeInsets){ .top = <#top#>, .leading = <#leading#>, .bottom = <#bottom#>, .trailing = <#trailing#> } (UIOffset){ .horizontal = <#horizontal#>, .vertical = <#vertical#> }
Nullability
Xcode 6.3.2 рдореЗрдВ, рдЕрд╢рдХреНрддрддрд╛ рдПрдиреЛрдЯреЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред Apple рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдЙрдиреНрд╣реЗрдВ рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдПрдкреАрдЖрдИ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рднрд╛рд╖рд╛ рдореЗрдВ рдХреБрдЫ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдореЗрдВ рд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдФрд░ рд╣рдо рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рд╣рдо рдПрдХ рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрд╢рдХреНрддрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕реАрдорд╛рдПрдВ рдХреНрдпрд╛ рд╣реИрдВред
рдЕрдкрдиреЗ рдЬреНрдЮрд╛рди рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк WWDC рд╕рддреНрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реА рдмрд╛рдд рд╣рдордиреЗ NS_ASSUME_NONNULL_BEGIN
/ NS_ASSUME_NONNULL_END
рдХреЛ .m
рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рдерд╛ред рд╣рд╛рде рд╕реЗ рдРрд╕рд╛ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реАрдзреЗ Xcode рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреИрдЪ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдордиреЗ рд╕рднреА рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЕрд╢рдХреНрддрддрд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред
рдпрджрд┐ рд╣рдо рдПрдХ рдореМрдЬреВрджрд╛ .m
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореИрдХреНрд░реЛрдЬрд╝ NS_ASSUME_NONNULL_BEGIN
/ NS_ASSUME_NONNULL_END
рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рддреБрд░рдВрдд рдкреВрд░реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд╛рдкрддрд╛ nullable
, null_resettable
рдФрд░ _Nullable
ред
рд╕рднреА рдЙрдкрдпреЛрдЧреА рдЕрд╢рдХреНрддрддрд╛ рд╕рдВрдХрд▓рдХ рдЪреЗрддрд╛рд╡рдиреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рд╣реИрдВред рд▓реЗрдХрд┐рди рдПрдХ рдЪрд░рдо рдЪреЗрддрд╛рд╡рдиреА рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛: -Wnullable-to-nonnull-conversion
(рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ "рдЕрдиреНрдп рдЪреЗрддрд╛рд╡рдиреА рдЭрдВрдбреЗ" рдореЗрдВ рд╕реЗрдЯ)ред рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕ рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рддрдм рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬрдм рдПрдХ рдЕрд╢рдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЪрд░ рдпрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЧреИрд░-рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд░реВрдк рд╕реЗ рдбрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИред
+ (NSString *)foo:(nullable NSString *)string { return string;
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, __auto_type
(рдФрд░ рдЗрд╕рд▓рд┐рдП let
рдФрд░ var
) рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЪреЗрддрд╛рд╡рдиреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИред __auto_type
рдорд╛рдзреНрдпрдо рд╕реЗ __auto_type
рдкреНрд░рдХрд╛рд░ рдЕрд╢рдХреНрддрддрд╛ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддрд╛ рд╣реИред рдФрд░, Apple рдбреЗрд╡рд▓рдкрд░ рдХреА рдЯрд┐рдкреНрдкрдгреА rdar: // 27062504 рдореЗрдВ рджреЗрдЦрддреЗ рд╣реБрдП , рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред рдпрд╣ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рддреМрд░ рдкрд░ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ _Nullable
рдпрд╛ _Nonnull
рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдХреБрдЫ рднреА рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
- (NSString *)test:(nullable NSString *)string { let tmp = string; return tmp;
nullable-to-nonnull-conversion
рдХреЛ рджрдмрд╛рдиреЗ рдХреЗ рд▓рд┐рдП nullable-to-nonnull-conversion
рд╣рдордиреЗ рдПрдХ рдореИрдХреНрд░реЛ рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ "рдмрд▓рдкреВрд░реНрд╡рдХ рдЕрдирдЯреНрд░реИрдк" рдХрд░рддрд╛ рд╣реИред RBBNotNil
рдореИрдХреНрд░реЛ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдЖрдЗрдбрд┐рдпрд╛ред рд▓реЗрдХрд┐рди __auto_type
рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ __auto_type
рд╕рд╣рд╛рдпрдХ рд╡рд░реНрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рд╕рдВрднрд╡ рдерд╛ред
#define JMNonnull(obj_) \ ({ \ NSCAssert(obj_, @"Expected `%@` not to be nil.", @#obj_); \ (typeof({ __auto_type result_ = (obj_); result_; }))(obj_); \ })
JMNonnull
рдореИрдХреНрд░реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
@interface JMRobot : NSObject @property (nonatomic, strong, nullable) JMLeg *leftLeg; @property (nonatomic, strong, nullable) JMLeg *rightLeg; @end @implementation JMRobot - (void)stepLeft { [self step:JMNonnull(self.leftLeg)] } - (void)stepRight { [self step:JMNonnull(self.rightLeg)] } - (void)step:(JMLeg *)leg {
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд▓реЗрдЦрди рдХреЗ рд╕рдордп, nullable-to-nonnull-conversion
рдЪреЗрддрд╛рд╡рдиреА nullable-to-nonnull-conversion
рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА nullable-to-nonnull-conversion
: рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрднреА рддрдХ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдЕрд╕рдорд╛рдирддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдПрдХ nullable
рдЪрд░ рдХреЛ nonnull
рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
- (NSString *)foo:(nullable NSString *)string { if (string != nil) { return string;
рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА ++ рдХреЛрдб рдореЗрдВ, рдЖрдк рдЗрд╕ if let
рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА ++ рдПрдХ if
рдореЗрдВ рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
- (NSString *)foo:(nullable NSString *)stringOrNil { if (let string = stringOrNil) { return string; } else { return @""; } }
рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ
рдФрд░ рднреА рдХрдИ рдЬрд╛рдиреЗ-рдорд╛рдиреЗ рдореИрдХреНрд░реЛрдЬрд╝ рдФрд░ рдХреАрд╡рд░реНрдб рд╣реИрдВ, рдЬрд┐рдирдХрд╛ рдореИрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛: @available
рдХреАрд╡рд░реНрдб, рдореИрдХреНрд░реЛрдЬрд╝ NS_DESIGNATED_INITIALIZER
, NS_UNAVAILABLE
, NS_REQUIRES_SUPER
, NS_NOESCAPE
, NS_ENUM
, NS_OPTIONS
(рдпрд╛ рдЖрдкрдХреЗ рдЕрдиреНрдп рдореИрдХреНрд░реЛрдЬрд╝)ред рд╣рдо рдпрд╣ рднреА рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдмрд╛рдХреА рдХреЗ libextobjc рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рджреЗрдЦреЗрдВред
рдФрд░ рдХреНрдпрд╛ рдкрдврд╝рдирд╛ рд╣реИ тЖТ рд▓реЗрдЦ рдХрд╛ рдХреЛрдб рдЬрд┐рд╕реНрдЯ рдореЗрдВ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдФрд░ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЬреЛ рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдХреЛрдб рдХреЗ рд▓реЗрдЦрди рдФрд░ рд╕рдорд░реНрдерди рдХреЛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рддрд╛ рд╣реИред рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рдЖрдк рд╕реНрд╡рд┐рдлреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдирдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХреЛ рдХреИрд╕реЗ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ (рд╡реЗ рднреА рдХреЗрд╕ рдХреНрд▓рд╛рд╕ рд╣реИрдВ; рд╡реЗ рдмреАрдЬреАрдп рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ , рдПрдбреАрдЯреА рднреА рд╣реИрдВ) рдФрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕реНрддрд░ рдкрд░ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред