(4/18)重学Standford_iOS7开发_框架和带属性字符串_课程笔记
第四课(干货课):
(最近要复习考试,有点略跟不上节奏,这节课的内容还是比较重要的,仔细理解掌握对今后的编程会有很大影响)
本节课主要涉及到Foundation和UIKit框架,基本都是概念与API知识,作者主要做一归纳整理。
0、其他
a.对象初始化
①通过alloc init(例如[[NSString alloc] initWithFormat:@"%d",2])
②通过类方法(例如[NSString StringWithFormat:@"%d",2])
③通过其他实例对象的方法(例如stringByAppendingString:)
b.nil
可以给nil发送消息,但只会得到nil
对于返回为struct类型的方法会返回未定义的类型
c.动态绑定
对象在执行期间(runtime)才会判断所引用对象的实际类型.
id(实质上为所有对象指针的类型如NSString *),这里讨论动态绑定主要为了明确哪些情况会出现编译警告与运行崩溃,方便后面讨论统一概念。
课程中的原例子:
1 @interface Vehicle 2 - (void)move; 3 @end 4 @interface Ship : Vehicle 5 - (void)shoot; 6 @end
情况①:属于正常使用情况,不会出现编译警告与崩溃。
1 Ship *s = [[Ship alloc] init]; 2 [s shoot]; 3 [s move];
情况②:父类调用子类特有方法,编译时会有警告,运行时正常运行。
1 Vehicle *v = s; 2 [v shoot];
情况③:任意id类型调用子类方法,无编译警告(因为类型为id),运行时若obj不为ship类,则会崩溃。若调用不存在的方法,则会出现编译警告(尽管类型为obj)
1 id obj = ...; 2 [obj shoot]; 3 [obj someMethodNameThatNoObjectAnywhereRespondsTo];
请况④:其他类型调用子类方法,会出现编译警告,若进行类型转换则没有编译警告,但仍会崩溃。
1 NSString *hello = @”hello”; 2 [hello shoot]; 3 Ship *helloShip = (Ship *)hello; 4 [helloShip shoot]; 5 [(id)hello shoot];
动态绑定的问题可能会引发严重的错误(如毫无节制的类型转换等)
解决动态绑定问题的思路:内省机制,协议
内省:NSObject基类提供了一系列的方法如isKindOfClass:(是否为这个类或其子类的实例),isMemberOfClass:(是否为这个类的实例),respondsToSelector:(对象是否响应某方法)来在运行时检测对象的类型。
检测方法的变量为选择器selector(SEL),使用方法如下:
1 if ([obj respondsToSelector:@selector(shoot)]) { 2 [obj shoot]; 3 } else if ([obj respondsToSelector:@selector(shootAt:)]) { 4 [obj shootAt:target]; 5 } 6 7 SEL shootSelector = @selector(shoot); 8 SEL shootAtSelector = @selector(shootAt:); 9 SEL moveToSelector = @selector(moveTo:withPenColor:);
1 [obj performSelector:shootSelector]; 2 [obj performSelector:shootAtSelector withObject:coordinate]; 3 4 [array makeObjectsPerformSelector:shootSelector]; // 用于数组,批量对数组中的对象发送消息 5 [array makeObjectsPerformSelector:shootAtSelector withObject:target]; // target is an id 6 7 [button addTarget:self action:@selector(digitPressed:) ...];//MVC中的target-action
1、Foundation
a.NSObject
所有类型的基类,提供了一系列通用的方法。
- (NSString *)description描述对象内容(格式化输出%@),一般在子类中自实现。
- (id)copy; // 尝试复制为不可变对象
- (id)mutableCopy; // 尝试复制为可变对象
b.NSArray
- (NSUInteger)count; - (id)objectAtIndex:(NSUInteger)index; //返回下标为index的数组元素 - (id)lastObject; // 返回数组末尾元素 - (id)firstObject; // 返回数组头元素 - (NSArray *)sortedArrayUsingSelector:(SEL)aSelector;//使用自定义方法对数组排序 - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)selectorArgument; - (NSString *)componentsJoinedByString:(NSString *)separator;//将数组转化为字符串并用separator分隔
c.NSMutableArray
1 + (id)arrayWithCapacity:(NSUInteger)numItems; // numItems is a performance hint only 2 + (id)array; // [NSMutableArray array] is just like [[NSMutableArray alloc] init] 3 4 - (void)addObject:(id)object; // 在尾部加入元素 5 - (void)insertObject:(id)object atIndex:(NSUInteger)index;//在下标index处插入元素 6 - (void)removeObjectAtIndex:(NSUInteger)index;//移除index处元素
数组的遍历:
1 NSArray *myArray = ...; 2 for (NSString *string in myArray) 3 { 4 // no way for compiler to know what myArray contains 5 double value = [string doubleValue]; // crash here if string is not an NSString 6 } 7 8 NSArray *myArray = ...; for (id obj in myArray) 9 { 10 // do something with obj, but make sure you don’t send it a message it does not respond to 11 if ([obj isKindOfClass:[NSString class]]) 12 { 13 // send NSString messages to obj with no worries 14 } 15 }
d.NSNumber
对常用基本类型的封装
1 NSNumber *n = [NSNumber numberWithInt:36]; 2 float f = [n floatValue]; 3 4 //便利初始化方式 5 NSNumber *three = @3; 6 NSNumber *underline = @(NSUnderlineStyleSingle); // enum 7 NSNumber *match = @([card match:@[otherCard]]);
e.其他简单类型
NSValue、NSData、NSDate(NSCalendar,NSDataFormatter,NSDateComponents)、NSSet(NSMutableSet)、NSOrderedSet(NSMutableOrderedSet)
f.NSDictionary
//初始化方式 @{ key1 : value1, key2 : value2, key3 : value3 } //查表方式 UIColor *colorObject = colors[colorString]; //常用方法 - (NSUInteger)count; - (id)objectForKey:(id)key;
g.NSMutableDictionary
1 //常用方法 2 - (void)setObject:(id)anObject forKey:(id)key;//添加键值 3 - (void)removeObjectForKey:(id)key;//移除键值 4 - (void)removeAllObjects; 5 - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;//合并字典
1 //遍历方式 2 NSDictionary *myDictionary = ...; 3 for (id key in myDictionary) 4 { 5 // do something with key here 6 id value = [myDictionary objectForKey:key]; 7 // do something with value here 8 }
h.属性列表
属性列表是一种保存数据的方式,定义为集合的集合,可以为NSArray, NSDictionary, NSNumber, NSString, NSDate, NSData。
可以对上述对象直接发送- (void)writeToFile:(NSString *)path atomically:(BOOL)atom;消息保存为属性列表文件
i.NSUserDefaults
轻量级的本地数据存储
[[NSUserDefaults standardUserDefaults] setArray:rvArray forKey:@“RecentlyViewed”]; //常用方法 - (void)setDouble:(double)aDouble forKey:(NSString *)key; - (NSInteger)integerForKey:(NSString *)key; // NSInteger is a typedef to 32 or 64 bit int - (void)setObject:(id)obj forKey:(NSString *)key; // obj must be a Property List - (NSArray *)arrayForKey:(NSString *)key; // will return nil if value for key is not NSArray //保存完毕后必须进行同步 [[NSUserDefaults standardUserDefaults] synchronize];
j.NSRange
1 typedef struct { 2 NSUInteger location; 3 NSUInteger length; 4 } NSRange; 5 6 //创建 7 NSMakeRange(NSUInteger location,NSUInteger length);
2、UIKit
a.UIColor
//系统内置颜色 [UIColor blackColor]; [UIColor blueColor]; [UIColor greenColor]; ... //RGB颜色 + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;//alpha为透明度 //HSB颜色 + (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha;
b.UIFont
//系统字体 UIKIT_EXTERN NSString *const UIFontTextStyleHeadline NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIFontTextStyleBody NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIFontTextStyleSubheadline NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIFontTextStyleFootnote NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIFontTextStyleCaption1 NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIFontTextStyleCaption2 NS_AVAILABLE_IOS(7_0); //新建字体 UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; //常用方法 + (UIFont *)systemFontOfSize:(CGFloat)pointSize; + (UIFont *)boldSystemFontOfSize:(CGFloat)pointSize;
c.UIFontDescriptor
1 //创建一个字体 2 + (UIFont *)fontWithDescriptor:(UIFontDescriptor *)descriptor size:(CGFloat)size; 3 4 //使用举例 5 UIFont *bodyFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; 6 UIFontDescriptor *existingDescriptor = [bodyFont fontDescriptor]; 7 UIFontDescriptorSymbolicTraits traits = existingDescriptor.symbolicTraits; 8 traits |= UIFontDescriptorTraitBold; 9 UIFontDescriptor *newDescriptor = [existingDescriptor fontDescriptorWithSymbolicTraits:traits]; 10 UIFont *boldBodyFont = [UIFont fontWithFontDescriptor:newDescriptor size:0];
d.Attributed Strings
①NSAttributeString
带属性的字符串(不是字符串),可通过字典设置一系列字符属性。
//获取特定范围的字符属性 - (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)range; //获取对应字符串 - (NSString *)string;
②NSMutableAttributeString
//常用的动态设定属性的方法 - (void)addAttributes:(NSDictionary *)attributes range:(NSRange)range; - (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range; - (void)removeAttribute:(NSString *)attributeName range:(NSRange)range; //转化为可变字符串 - (NSMutableString *)mutableString
//举例 UIColor *yellow = [UIColor yellowColor]; UIColor *transparentYellow = [yellow colorWithAlphaComponent:0.3]; //字符串属性字典 @{ NSFontAttributeName : [UIFont preferredFontWithTextStyle:UIFontTextStyleHeadline] NSForegroundColorAttributeName : [UIColor greenColor], NSStrokeWidthAttributeName : @-5, NSStrokeColorAttributeName : [UIColor redColor], NSUnderlineStyleAttributeName : @(NSUnderlineStyleNone), NSBackgroundColorAttributeName : transparentYellow }
1 //for UIButton 2 - (void)setAttributedTitle:(NSAttributedString *)title forState:...; 3 //for UILable 4 @property (nonatomic, strong) NSAttributedString *attributedText; 5 //for UITextView 6 @property (nonatomic, readonly) NSTextStorage *textStorage;
3、作业
无
其它:本节课主要是理论铺垫,着重API的讲解,都是很常用的对象,因此务必做到熟练使用,在今后的iOS开发中才不会出现基础问题。希望大家可以多多查阅文档,实际编程时重点理解动态绑定等概念。
课程视频地址:网易公开课:http://open.163.com/movie/2014/1/B/P/M9H7S9F1H_M9H7VPRBP.html
或者iTunes U搜索standford课程