2018 рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдкрд░ рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВред рднрд╛рдЧ 1

рдЕрдзрд┐рдХрд╛рдВрд╢ 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 

 //  NSArray<NSString *> *const items = [string componentsSeparatedByString:@","]; void(^const completion)(NSData * _Nullable, NSURLResponse * _Nullable, NSError * _Nullable) = ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // ... }; //  let items = [string componentsSeparatedByString:@","]; let completion = ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // ... }; 

рдпрджрд┐ рдЖрдк рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдХреНрд▓рд╛рд╕ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░ рдХреЗ рдмрд╛рдж 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"; }; // `block`   `NSString *(^const)(void)` 

рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдЖрдк ReactiveObjC рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХрдИ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИрдВ рдЬрд┐рдирдХреЗ рддрд╣рдд рдЖрдкрдХреЛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


  1. рдпрджрд┐ рдХрд┐рд╕реА рдмреНрд▓реЙрдХ рдореЗрдВ рдХрдИ return рд╣реИрдВ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред


     let block1 = ^NSUInteger(NSUInteger value){ if (value > 0) { return value; } else { // `NSNotFound`   `NSInteger` return NSNotFound; } }; let block2 = ^JMSomeBaseClass *(BOOL flag) { if (flag) { return [[JMSomeBaseClass alloc] init]; } else { // `JMSomeDerivedClass`   `JMSomeBaseClass` return [[JMSomeDerivedClass alloc] init]; } }; 

  2. рдпрджрд┐ рдмреНрд▓реЙрдХ рдореЗрдВ return рд╣реИ рдЬреЛ nil рд▓реМрдЯрд╛рддрд╛ рд╣реИред


     let block1 = ^NSString * _Nullable(){ return nil; }; let block2 = ^NSString * _Nullable(BOOL flag) { if (flag) { return @"abc"; } else { return nil; } }; 

  3. рдпрджрд┐ рдмреНрд▓реЙрдХ рдХреЛ 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_)) 

рдЕрдм рд╣рдорд╛рд░рд╛ рдХреЛрдб рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИ:


 //  for (MyItemClass *item in items) { NSLog(@"%@", item); } //  foreach (item, items) { NSLog(@"%@", item); } 

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]; // ... //  let itemsCopy = (NSArray<NSString *> *)[items copy]; //  let itemsCopy = [items copy]; 

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]; // Warning: Ignoring return value of function declared with 'warn_unused_result' attribute. 

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 рдХреЗ рд▓рд┐рдП рд╢рд╛рдмреНрджрд┐рдХ рд╢реБрд░реБрдЖрдд рдХреА, рд╕рд╛рде рд╣реА рд╕рд╛рде рдмреЙрдХреНрд╕рд┐рдВрдЧ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рднреА рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдПред рдЖрдк рдХреНрд▓реИрдВрдЧ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


 //  @YES // [NSNumber numberWithBool:YES] @NO // [NSNumber numberWithBool:NO] @123 // [NSNumber numberWithInt:123] @3.14 // [NSNumber numberWithDouble:3.14] @[obj1, obj2] // [NSArray arrayWithObjects:obj1, obj2, nil] @{key1: obj1, key2: obj2} // [NSDictionary dictionaryWithObjectsAndKeys:obj1, key1, obj2, key2, nil] // Boxed expressions @(boolVariable) // [NSNumber numberWithBool:boolVariable] @(intVariable) // [NSNumber numberWithInt:intVariable)] 

рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдмреВрд▓рд┐рдпрди рдорд╛рди рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓рдкреЗрдЯрддреА рд╣реИ, рдЖрдкрдХреЛ рдХреБрдЫ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 //  `NSDirectionalEdgeInsets`  `NSValue` let insets = (NSDirectionalEdgeInsets){ ... }; let value = [[NSValue alloc] initWithBytes:&insets objCType:@encode(typeof(insets))]; // ... //  `NSDirectionalEdgeInsets`  `NSValue` var insets = (NSDirectionalEdgeInsets){}; [value getValue:&insets]; 

рдХреБрдЫ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐рдпрд╛рдБ рдФрд░ рдЧреБрдг рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ (рдЬреИрд╕реЗ +[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 *` 

рдЖрдкрдХреЛ рдЕрднреА рднреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд╛рдкрд╕ -[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 рдлрд╝рдВрдХреНрд╢рди рдХреА рдШреЛрд╖рдгрд╛ рдХреЛ рджреЗрдЦрдирд╛ рдерд╛), рдлрд┐рд░ рдХрдВрдкрд╛рдЙрдВрдб рд╢рд╛рдмреНрджрд┐рдХ рдХреЗ рд╕рд╛рде рдХреЛрдб рдЦреБрдж рдХреЗ рд▓рд┐рдП рдмреЛрд▓рддрд╛ рд╣реИ:


 //  UIEdgeInsetsMake(1, 2, 3, 4) //  (UIEdgeInsets){ .top = 1, .left = 2, .bottom = 3, .right = 4 } 

рдЦреЗрддреЛрдВ рдореЗрдВ рд╕реЗ рдХреБрдЫ рд╢реВрдиреНрдп рд╣реЛрдиреЗ рдкрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ:


 (CGPoint){ .y = 10 } //  (CGPoint){ .x = 0, .y = 10 } (CGRect){ .size = { .width = 10, .height = 20 } } //  (CGRect){ .origin = { .x = 0, .y = 0 }, .size = { .width = 10, .height = 20 } } (UIEdgeInsets){ .top = 10, .bottom = 20 } //  (UIEdgeInsets){ .top = 20, .left = 0, .bottom = 10, .right = 0 } 

рдмреЗрд╢рдХ, рдпреМрдЧрд┐рдХ рд╢рд╛рдмреНрджрд┐рдХ рдореЗрдВ рдЖрдк рди рдХреЗрд╡рд▓ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рднрд╛рд╡:


 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; // Implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' } 

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, __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 { // ... } @end 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд▓реЗрдЦрди рдХреЗ рд╕рдордп, nullable-to-nonnull-conversion рдЪреЗрддрд╛рд╡рдиреА nullable-to-nonnull-conversion рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА nullable-to-nonnull-conversion : рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрднреА рддрдХ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдЕрд╕рдорд╛рдирддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдПрдХ nullable рдЪрд░ рдХреЛ nonnull рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


 - (NSString *)foo:(nullable NSString *)string { if (string != nil) { return string; // Implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' } else { return @""; } } 

рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА ++ рдХреЛрдб рдореЗрдВ, рдЖрдк рдЗрд╕ 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 рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рджреЗрдЦреЗрдВред



тЖТ рд▓реЗрдЦ рдХрд╛ рдХреЛрдб рдЬрд┐рд╕реНрдЯ рдореЗрдВ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдирд┐рд╖реНрдХрд░реНрд╖


рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдФрд░ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЬреЛ рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдХреЛрдб рдХреЗ рд▓реЗрдЦрди рдФрд░ рд╕рдорд░реНрдерди рдХреЛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рддрд╛ рд╣реИред рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рдЖрдк рд╕реНрд╡рд┐рдлреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдирдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХреЛ рдХреИрд╕реЗ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ (рд╡реЗ рднреА рдХреЗрд╕ рдХреНрд▓рд╛рд╕ рд╣реИрдВ; рд╡реЗ рдмреАрдЬреАрдп рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ , рдПрдбреАрдЯреА рднреА рд╣реИрдВ) рдФрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕реНрддрд░ рдкрд░ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред

Source: https://habr.com/ru/post/hi431236/


All Articles