日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Runtime的应用

發布時間:2023/11/29 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Runtime的应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自:http://www.imlifengfeng.com/blog/?p=397 1、快速歸檔

  • (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [self setValue:[aDecoder decodeObjectForKey:key] forKey:key]; } } return self; }

  • (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [aCoder encodeObject:[self valueForKey:key] forKey:key]; } }

2、Json到Model的轉化

  • (instancetype)initWithDict:(NSDictionary *)dict {

    if (self = [self init]) { //(1)獲取類的屬性及屬性對應的類型 NSMutableArray * keys = [NSMutableArray array]; NSMutableArray * attributes = [NSMutableArray array]; /* * 例子 * name = value3 attribute = T@"NSString",C,N,V_value3 * name = value4 attribute = T^i,N,V_value4 */ unsigned int outCount; objc_property_t * properties = class_copyPropertyList([self class], &outCount); for (int i = 0; i < outCount; i ++) { objc_property_t property = properties[i]; //通過property_getName函數獲得屬性的名字 NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; [keys addObject:propertyName]; //通過property_getAttributes函數可以獲得屬性的名字和@encode編碼 NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; [attributes addObject:propertyAttribute]; } //立即釋放properties指向的內存 free(properties);

    //(2)根據類型給屬性賦值for (NSString * key in keys) {if ([dict valueForKey:key] == nil) continue;[self setValue:[dict valueForKey:key] forKey:key];} 復制代碼

    } return self; }

3、Category添加屬性并生成getter和setter方法 #import <Foundation/Foundation.h>

@interface NSArray (MyCategory) //不會生成添加屬性的getter和setter方法,必須我們手動生成 @property (nonatomic, copy) NSString *blog; @end

#import "NSArray+MyCategory.h" #import <objc/runtime.h>

@implementation NSArray (MyCategory)

// 定義關聯的key static const char *key = "blog";

/** blog的getter方法 */

  • (NSString *)blog { // 根據關聯的key,獲取關聯的值。 return objc_getAssociatedObject(self, key); }

/** blog的setter方法 */

  • (void)setBlog:(NSString *)blog { // 第一個參數:給哪個對象添加關聯 // 第二個參數:關聯的key,通過這個key獲取 // 第三個參數:關聯的value // 第四個參數:關聯的策略 objc_setAssociatedObject(self, key, blog, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end

4、Method Swizzling使用 #import "UIViewController+swizzling.h" #import <objc/runtime.h> @implementation UIViewController (swizzling)

  • (void)load { // 通過class_getInstanceMethod()函數從當前對象中的method list獲取method結構體,如果是類方法就使用class_getClassMethod()函數獲取。 Method fromMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method toMethod = class_getInstanceMethod([self class], @selector(swizzlingViewDidLoad)); /**
    • 我們在這里使用class_addMethod()函數對Method Swizzling做了一層驗證,如果self沒有實現被交換的方法,會導致失敗。
    • 而且self沒有交換的方法實現,但是父類有這個方法,這樣就會調用父類的方法,結果就不是我們想要的結果了。
    • 所以我們在這里通過class_addMethod()的驗證,如果self實現了這個方法,class_addMethod()函數將會返回NO,我們就可以對其進行交換了。 */ if (!class_addMethod([self class], @selector(swizzlingViewDidLoad), method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) { method_exchangeImplementations(fromMethod, toMethod); } }

// 我們自己實現的方法,也就是和self的viewDidLoad方法進行交換的方法。

  • (void)swizzlingViewDidLoad { NSString *str = [NSString stringWithFormat:@"%@", self.class]; // 我們在這里加一個判斷,將系統的UIViewController的對象剔除掉 if(![str containsString:@"UI"]){ NSLog(@"統計打點 : %@", self.class); } [self swizzlingViewDidLoad]; } @end

5、Method Swizzling類簇 __NSArrayI才是NSArray真正的類 #import "NSArray+ MyArray.h" #import "objc/runtime.h" @implementation NSArray MyArray)

  • (void)load {//是加載文件到內存執行的方法 跟類的生命周期沒有關系 Method fromMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:)); Method toMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(my_objectAtIndex:)); method_exchangeImplementations(fromMethod, toMethod); }
  • (id)my_objectAtIndex:(NSUInteger)index { if (self.count-1 < index) { // 這里做一下異常處理,不然都不知道出錯了。 @try { return [self my_objectAtIndex:index]; } @catch (NSException *exception) { // 在崩潰后會打印崩潰信息,方便我們調試。 NSLog(@"---------- %s Crash Because Method %s ----------\n", class_getName(self.class), func); NSLog(@"%@", [exception callStackSymbols]); return nil; } @finally {} } else { return [self my_objectAtIndex:index]; } } @end

總結

以上是生活随笔為你收集整理的Runtime的应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。