贾汪建设局网站医药企业网站建设要哪些备案

当前位置: 首页 > news >正文

贾汪建设局网站,医药企业网站建设要哪些备案,营销手机都有什么功能啊,国外很炫酷的网站文章目录 KVC的定义 容器类中KVC的实现 KVC设值 KVC取值 KVC使用KeyPath KVC处理异常 KVC处理设值nil异常 KVC处理UndefinedKey异常 KVC处理数值和结构体类型属性 KVC键值验证 KVC处理集合 简单集合运算符 对象运算符 KVC处理字典 KVC应用 动态地取值和设值 用…文章目录 KVC的定义 容器类中KVC的实现 KVC设值 KVC取值 KVC使用KeyPath KVC处理异常 KVC处理设值nil异常 KVC处理UndefinedKey异常 KVC处理数值和结构体类型属性 KVC键值验证 KVC处理集合 简单集合运算符 对象运算符 KVC处理字典 KVC应用 动态地取值和设值 用KVC来访问和修改私有变量 Model和字典转换 修改一些控件的内部属性 操作集合 用KVC实现高阶消息传递 实现KVO KVC的定义 定义KVCKey-value coding键值编码是指iOS开发中允许开发者通过key名直接访问对象的属性或者给对象的属性赋值而不需要调用明确的存取方法。使用KVC键值编码的好处就是可以在运行时动态地访问和修改对象的属性而不是在编译时确定。 注意在实现了访问器方法的类中使用点语法和KVC访问对象差别不大二者可以混用。但是在没有访问器方法的类中无法使用点语法这时KVC就有优势了。 KVC的定义都是对NSObject的扩展来实现的OC语言中有一个显示的NSKeyValueCoding类别名所以所有继承了NSObject的类型都能使用KVC一些没有继承NSObject的纯Swift类和结构体不支持KVC下面是KVC最重要的四个方法

  • (nullable id)valueForKey:(NSString *)key;//直接通过Key来取值
  • (void)setValue:(nullable id)value forKey:(NSString *)key;//通过Key来取值
  • (nullable id)valueForKeyPath:(NSString *)keyPath;//通过KeyPath来取值
  • (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;//通过KeyPath来设值 此外在NSKeyValueCoding这个类别中还有一些其他的方法 (BOOL)accessInstanceVariablesDirectly; //默认返回YES表示如果没有找到SetKey这个存取方法的话会按照_key, _iskey, key, iskey的顺序搜索成员重写方法设置成返回NO就不会这样搜索也就是说如果没找到SetKey这个方法就不会再继续搜索
  • (BOOL)validateValue:(inout id __nullable * __)ioValue forKey:(NSString *)inKey error:(out NSError **)outError; //KVC提供属性值正确性验证的API可以用来检查set的值是否正确为不正确的值做一个替换值或者拒绝设置新值并返回错误原因通过outError参数来返回错误原因
  • (NSMutableArray )mutableArrayValueForKey:(NSString)key; //集合操作的API如果属性是一个NSMutableArray那么可以用这个方法来返回这个NSMutableArray在类别里面还有类似的API来对set操作
  • (nullable id)valueForUndefinedKey:(NSString *)key; //如果key不存在且KVC无法搜索到任何和key有关的字段或属性则会调用这个方法默认抛出异常
  • (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key; //这个方法也是针对key不存在的情况进行的操作不过这个方法是在设值时操作
  • (void)setNilValueForKey:(NSString *)key; //如果在SetValue时为方法传入的参数是nil也就是说给Value传一个nil就会调用这个方法
  • (NSDictionaryNSString *, id *)dictionaryWithValuesForKeys:(NSArrayNSString * *)keys; //输入一组key返回该组key对应的value再转回字典返回 关于validateValue:ioValue forKey:in**Key error:outError 这个方法这里给出一个使用的示例可以使用这个方法来对设置的属性值进行验证这里以验证是否为空为例 首先在自定义的类中实现这个方法
  • (BOOL)validateValue:(inout id __nullable *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError {// 检查键名if ([inKey isEqualToString:name]) {NSString *name (NSString *)*ioValue;// 验证值是否为空if (name.length 0) {if (outError) {*outError [NSError errorWithDomain:MyDomaincode:1001userInfo:{NSLocalizedDescriptionKey: Name cannot be empty.}];}return NO; // 验证失败}}return YES; // 验证成功 } 然后在设置属性值时调用此方法进行验证 NSError *error nil; NSString name ; if (![self validateValue:name forKey:name error:error]) {NSLog(Validation failed: %, error.localizedDescription); } else {self.name name; // 设置有效的值 } 容器类中KVC的实现 在自定义容器类时KVC有特殊的实现 苹果原生的容器类比如NSArray或者NSSet等都已经实现了对应的方法。 对于有序集合 -countOfKey //必须实现对应NSArray的方法count: -objectInKeyAtIndex: -KeyAtIndexes: //这两个方法必须实现一个对应NSArray的方法objectAtIndex: 和objectsAtIndexes: -getKey:range: //不是必须实现对应NSArray方法getObjects:range: -insertObject:inKeyAtIndex: -insertKey:atIndexes: //两个必须实现一个类似NSMutableArray的方法insertObject: atIndex: 和insertObjects: atIndexes: -replaceObejctInKeyAtIndex: withObject: -replaceKeyAtIndexes: withKey://可选的是一种替换元素的方法 对于无序集合 -countOfKey //必须实现对应NSSet -objectInKeyAtIndex: //由于NSSet是无序的此方法可以选择性实现 -KeyAtIndexes: //和上一个方法一样选择性实现 -getKey: range: //不是必须实现对应NSArray的getObjects: range:方法无序一般不适用 -insertObject:inKeyAtIndex: //无序集合一般不支持索引插入 -insertKey:atIndexes: //和上一个方法一样 -removeObjectFromKeyAtIndex: //和前两个一样 -removeKeyAtIndexes: //和之前一样 -replaceObejctInKeyAtIndex: withObject: -replaceKeyAtIndexes: withKey: //都和之前一样 一上就是KVC的定义和KVC有关的一些方法 KVC设值 通过KVC设值时会在对象中寻找对应的key当调用setValue: forKey:时有一个寻找key的顺序 优先调用setKey: 通过setter方法完成设置。 如果未找到setKey:方法会先检查 (BOOL)accessInstanceVariablesDirectly方法有没有返回YES默认返回YES如果重写该方法返回NO的话那么这一步KVC会执行setValue: forUndefinedKey: 方法。如果返回YES会在该类里面搜索有没有名为_key的成员变量无论该变量是在类接口定义还是在实现处定义也无论使用什么修饰关键字。 如果没有setKey:方法也没有_key成员变量就会搜索 _isKey成员的变量。 如果以上都没有就会继续搜索Key和isKey的成员变量 如果方法和相应成员变量全都不存在就会执行setValue: forUndefinedKey: 方法默认抛出异常
    简单来说如果没有找到SetKey方法会按照_Key _isKeyKeyisKey的顺序搜索成员并进行赋值操作。 来尝试一下寻找_Key的成员变量 interface KVCMethod : NSObject {NSString
    _FirstName; } endint main(int argc, char * argv[]) {NSString * appDelegateClassName;autoreleasepool {KVCMethod* kvcMethod [[KVCMethod alloc] init];[kvcMethod setValue:李 forKey:FirstName];NSLog(%, [kvcMethod valueForKey:FirstName]);}appDelegateClassName NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName); } ​ 这里将后续的代码删去了所以只用看第一行输出的结果可以看到运行的结果是成功找到了_key成员变量并且成功设置和取出了相应的成员变量 再将accessInstanceVariablesDirectly设置为NO运行 我们重写处理异常的方法来检查修改accessInstanceVariablesDirectly的返回值之后程序是怎么执行的 implementation KVCMethod ​
  • (BOOL)validateValue:(inout id  _Nullable autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError *autoreleasing  _Nullable )outError {if ([inKey isEqualToString:name]) {NSString name (NSString*)*ioValue;if (name.length 0) {if (outError) {*outError [NSError errorWithDomain:MyDoain code:1001 userInfo:{NSLocalizedDescriptionKey: Name cannot be empty}];}return NO;}}return YES; } ​(BOOL)accessInstanceVariablesDirectly {return NO; } ​
  • (id)valueForUndefinedKey:(NSString *)key {NSLog(出现异常不存在该key:%, key);return nil; } ​
  • (void)setValue:(id)value forUndefinedKey:(NSString *)key {NSLog(出现异常不存在该key:%, key); } ​ end 运行结果如下 可以发现触发了处理异常的方法也就是说程序没有按照之前的顺序寻找成员变量也就没有成功赋值程序输出NULL KVC取值 当调用valueForKey: name的代码时KVC对key的都搜索方式不同于setValue: forKey: 其搜索方式如下 首先按照getKeyKeyisKey的顺序查找getter方法找到的话会直接调用。如果是BOOL或者int等值类型会将其包装成一个NSNumber对象 如果没有找到getter方法就会查找countOfobjectIn AtIndex 或者AtIndexes 格式的方法如果其中一个被找到就会返回一个可以相应NSArray所有方法的代理集合NSKeyValueArray属于NSArray的子类调用这个代理集合的方法或者说给它发送属于NSArray的方法就会以countOfobjectIn Atindex或AtIndexes这几个方法组合的形式调用。 如果上面方法都没有找到就会同时查照countOfenumeratorOfmerberOf格式的方法这三个方法都找到了的话那么就返回一个可以相应NSSet所有方法的代理集合和上面所说一样给这个代理集合发送NSSet的方法就会以countOfenumeratorOfmerberOf组合的形式调用。 如果还没有找到这时候就会检查方法accessInstanceVariablesDirectly的返回值如果是YES就会按照之前设值一样的顺序搜索_Key _isKeyKeyisKey。
    KVC使用KeyPath 当自定义类的成员变量是自定义类或者其他的复杂数据类型时可以先使用KVC获取该属性然后再用一次KVC获得这个属性的属性。但这种方法比较繁琐KVC有一种更简洁的方法那就是键路径KeyPath按照路径寻找Key
  • (nullable id)valueForKeyPath:(NSString *)keyPath;                  //通过KeyPath来取值
  • (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;  //通过KeyPath来设值 int main(int argc, char * argv[]) {NSString * appDelegateClassName;autoreleasepool {KVCMethod* kvcMethod [[KVCMethod alloc] init];SubKVCMethod* subKVCMethod [[SubKVCMethod alloc] init];[kvcMethod setValue:subKVCMethod forKey:subKVCMethod];[kvcMethod setValue:南崩 forKeyPath:subKVCMethod.name];NSLog(KVCMethod的属性SubKVCMethod的属性name是%, [kvcMethod valueForKeyPath:subKVCMethod.name]);}appDelegateClassName NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName); }运行的结果是 发现成功实现了赋值和取值操作并且这里KeyPath的格式其实就类似于我们点语法的格式 KVC处理异常 之前其实已经提到过KVC处理异常的方法了这里主要是两种异常一种是使用了错误的Key另一种是设值时传递了nil的值分别可以使用两类方法来处理 KVC处理设值nil异常 KVC一般不允许在调用setValue: forKey: 时传递一个nil的值。如果传入一个nil的值KVC会调用setNilValueForKey:方法这个方法默认抛出异常。 #import KVCMethod.h ​ implementation KVCMethod ​
  • (void)setNilValueForKey:(NSString *)key {NSLog(不能将%设成nil, key); } ​ end KVC处理UndefinedKey异常 当调用setValue: forKey或者valueForKey时一般不允许使用不存在的Key否则会报错forUndefinedKey发生崩溃重写forUndefinedKey可以避免崩溃 implementation KVCMethod ​
  • (id)valueForUndefinedKey:(NSString *)key {NSLog(出现异常不存在该key:%, key);return nil; } ​
  • (void)setValue:(id)value forUndefinedKey:(NSString *)key {NSLog(出现异常不存在该key:%, key); } ​ end KVC处理数值和结构体类型属性 valueForKey: 方法总是会返回一个id对象如果原本的变量类型是值类型或者结构体返回值会封装成NSNumber或者NSValue对象这两个类会处理数字、布尔值、指针和结构体。 在使用setValue: forKey时必须手动将值类型转换成NSNumber或者NSValue类型才能传递过去因为传递进去和取出来的都是id类型所以需要自己确保类型正确性运行时如果类型错误会抛出异常 interface KVCMethod : NSObject ​ property(nonatomic, readwrite, assign)int age; ​ end int main(int argc, char * argv[]) {NSString * appDelegateClassName;autoreleasepool {KVCMethod* kvcMethod [[KVCMethod alloc] init];[kvcMethod setValue:[NSNumber numberWithInt:23] forKey:age];NSLog(age %, [kvcMethod valueForKey:age]);appDelegateClassName NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName); } ​ 这里就是为类添加了一个int类型的属性age我们赋给age的是一个NSNumber对象KVC会自动的将NSNumber对象转换成int对象然后再调用相应的访问器方法设置age的值。 使用valueForKey:方法时返回的值是一个NSNumber。 需要注意的是我们不能直接将数值通过KVC赋值需要先转换为NSNumber和NSValue类型那么哪些类型用NSNumber封装哪些用NSValue呢 可以使用NSNumber的数据类型 (NSNumber)numberWithChar:(char)value;(NSNumber)numberWithUnsignedChar:(unsignedchar)value;(NSNumber)numberWithShort:(short)value;(NSNumber)numberWithUnsignedShort:(unsignedshort)value;(NSNumber)numberWithInt:(int)value;(NSNumber)numberWithUnsignedInt:(unsignedint)value;(NSNumber)numberWithLong:(long)value;(NSNumber)numberWithUnsignedLong:(unsignedlong)value;(NSNumber)numberWithLongLong:(longlong)value;(NSNumber)numberWithUnsignedLongLong:(unsignedlonglong)value;(NSNumber)numberWithFloat:(float)value;(NSNumber)numberWithDouble:(double)value;(NSNumber)numberWithBool:(BOOL)value;(NSNumber)numberWithInteger:(NSInteger)valueNS_AVAILABLE(10_5,2_0);(NSNumber)numberWithUnsignedInteger:(NSUInteger)valueNS_AVAILABLE(10_5,2_0); 可以使用NSValue的数据类型 (NSValue)valueWithCGPoint:(CGPoint)point;(NSValue)valueWithCGSize:(CGSize)size;(NSValue)valueWithCGRect:(CGRect)rect;(NSValue)valueWithCGAffineTransform:(CGAffineTransform)transform;(NSValue)valueWithUIEdgeInsets:(UIEdgeInsets)insets;(NSValue*)valueWithUIOffset:(UIOffset)insetsNS_AVAILABLE_IOS(5_0); NSValue主要用于处理结构体类型的数据任何结构体都可以转化成NSValue对象包括自定义的结构体 KVC键值验证 KVC有提供验证Key对应的Value是否合法的方法
  • (BOOL)validateValue:(inoutid)ioValue forKey:(NSString)inKey error:(outNSError**)outError; 这个方法在KVC的定义那个部分已经有过讲解这里就不多赘述了。 KVC处理集合 简单集合运算符 简单集合运算符有avg countmaxminsum5种这五种运算符分别表示平均值总个数最大值最小值和总量 int main(int argc, char * argv[]) {NSString * appDelegateClassName;autoreleasepool {KVCMethod* kvcMethod1 [[KVCMethod alloc] init];kvcMethod1.name 灰灰;kvcMethod1.age 12;KVCMethod* kvcMethod2 [[KVCMethod alloc] init];kvcMethod2.name 黑黑;kvcMethod2.age 22;KVCMethod* kvcMethod3 [[KVCMethod alloc] init];kvcMethod3.name 白白;kvcMethod3.age 32;NSArray* array [NSArray arrayWithObjects:kvcMethod1, kvcMethod2, kvcMethod3, nil];NSNumber* sum [array valueForKeyPath:sum.age];NSLog(sum %, sum);NSNumber* avg [array valueForKeyPath:avg.age];NSLog(avg %, avg);NSNumber* count [array valueForKeyPath:count.age];NSLog(count %, count);NSNumber* min [array valueForKeyPath:min.age];NSLog(min %, min);NSNumber* max [array valueForKeyPath:max.age];NSLog(max %, max);appDelegateClassName NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName); } ​ 对象运算符 以数组的形式返回指定内容有两种 distinctUnionOfObjects unionOfObjects 他们的返回值都是NSArray区别是前者返回元素唯一是去重后的结果后者返回全集。 KVC处理字典 有两个关于NSDictionary的方法
  • (NSDictionaryNSString *, id *)dictionaryWithValuesForKeys:(NSArrayNSString * *)keys;
  • (void)setValuesForKeysWithDictionary:(NSDictionaryNSString *, id )keyedValues; 第一个方法是指输入一组key返回这组key对应的属性再组成一个字典 第二个方法是用来修改Model中对应Key的属性 interface Address : NSObject ​ property (nonatomic, copy)NSString country; property (nonatomic, copy)NSString* province; property (nonatomic, copy)NSString* city; property (nonatomic, copy)NSString* district; ​ end​ int main(int argc, char * argv[]) {NSString * appDelegateClassName;autoreleasepool {//模型转字典Address* add [Address new];add.country China;add.province Guang Dong;add.city Shen Zhen;add.district Nan Shan;NSArray* arr [country,province,city,district];NSDictionary* dict [add dictionaryWithValuesForKeys:arr]; //把对应key所有的属性全部取出来NSLog(%,dict);//字典转模型NSDictionary* modifyDict {country:USA,province:california,city:Los angle};[add setValuesForKeysWithDictionary:modifyDict];            //用key Value来修改Model的属性NSLog(country:% province:% city:%,add.country,add.province,add.city); ​appDelegateClassName NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName); } KVC应用 KVC这种基于运行时的编程方式具有很高的灵活性因此在iOS开发中有着广泛的用途 动态地取值和设值 利用KVC动态的取值和设值是最基本的用途了。 用KVC来访问和修改私有变量 对于类里的私有属性Objective-C是无法直接访问的但是KVC是可以的。 Model和字典转换 这是KVC强大作用的又一次体现KVC和Objc的runtime组合可以很容易的实现Model和字典的转换。 修改一些控件的内部属性 这也是iOS开发中必不可少的小技巧。众所周知很多UI控件都由很多内部UI控件组合而成的但是Apple度没有提供这访问这些控件的API这样我们就无法正常地访问和修改这些控件的样式。 而KVC在大多数情况可下可以解决这个问题。最常用的就是个性化UITextField中的placeHolderText了。 操作集合 Apple对KVC的valueForKey:方法作了一些特殊的实现比如说NSArray和NSSet这样的容器类就实现了这些方法。所以可以用KVC很方便地操作集合。 用KVC实现高阶消息传递 当对容器类使用KVC时valueForKey:将会被传递给容器中的每一个对象而不是容器本身进行操作。结果会被添加进返回的容器中这样开发者可以很方便的操作集合来返回另一个集合。 实现KVO KVO是基于KVC实现的下面讲一下KVO的概念和实现。