iOS RunTime你知道了總得用一下

來源:互聯網
上載者:User

標籤:

說點題外話:

      我剛來現在這家公司的時候,老闆讓我下載一個脈脈,上去找找自己的同行,多認識些同行。其實初衷的好的,但最近這兩天我把它卸載了,不為別的,負能量太多!iOS這行自從2016就沒景氣過,在這行混,這些自己也肯定都知道。但就是受不鳥鋪天蓋地的多久沒找到工作,滿大街都是iOS程式猿這些話題。看了也給我帶不來任何的作用,你唯一能做的就是安安靜靜的做好自己該做的。自己入iOS這行也一年半過了,除去培訓的那個幾個月,真正摸爬滾打也一年多了,有時候想想,其實也沒覺得有多差,以後怎樣不知道,但至少現在,你有份工作,有口飯吃,還有時間給你去學,有什麼不知足的呢?在我自己淺薄的意識裡,編程思想都是相同的,喜歡iOS你也可能也會喜歡安卓,Java,JS,PHP等等等。。活到老,學到老,那顆不停的去學的心就是自己最大的依靠。

迴歸正題:

    以前有瞭解過Runtime,不記得是幾個月前的事情了,最近又遇到這個問題,還是總結一下吧,總結的不好的地方,見諒了。。

      Runtime俗稱“運行時”,項目都有分一個編譯和運行兩個狀態,這個應該瞭解。是一套底層的C語言的API。OC是一門動態語言,有些東西不會放在我們編譯的時候去處理,會等到運行時去處理。下面說的這些,建議大家隨表這個項目,匯入下面標頭檔點進去我們一起慢慢探討!

#import <objc/runtime.h>

看看他最上面:

/// An opaque type that represents a method in a class definition.typedef struct objc_method *Method;  // 方法/// An opaque type that represents an instance variable.typedef struct objc_ivar *Ivar;   // 變數/// An opaque type that represents a category.typedef struct objc_category *Category;  // 類別也叫分類/// An opaque type that represents an Objective-C declared property.typedef struct objc_property *objc_property_t; // 屬性

定義在上面代碼的注釋裡我們說了,再往下看你就看到的是類的表示:

struct objc_class {    Class isa  OBJC_ISA_AVAILABILITY;#if !__OBJC2__    Class super_class                                        OBJC2_UNAVAILABLE;    const char *name                                         OBJC2_UNAVAILABLE;    long version                                             OBJC2_UNAVAILABLE;    long info                                                OBJC2_UNAVAILABLE;    long instance_size                                       OBJC2_UNAVAILABLE;    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;#endif} OBJC2_UNAVAILABLE;/* Use `Class` instead of `struct objc_class *` */

Class super_class指向父類。

const char *name  類的名字long version 類的版本資訊,初始化預設為0,下面有函數class_setVersion和class_getVersion可以對它進行進行修改和讀

long info 標識。

long instance_size 類的執行個體變數的大小,包括繼承的父類的。

struct objc_ivar_list *ivars 成員變數的地址。

struct objc_method_list **methodLists 

struct objc_cache *cache 指向最近使用的方法的指標struct objc_protocol_list *protocols 遵守的協議。

下面就是一系列的方法了,這裡總結常見的,在下面的代碼注釋裡面會說的比較詳細點:

#import "ViewController.h"#import <objc/runtime.h>/** *  定義一個測試的協議 */@protocol protocolTestDelegate <NSObject>@optional  -(void)protocolTestDelegate;@end@interface ViewController ()/** *   定義三個測試的屬性 */@property (nonatomic,strong) NSString * testString1;@property (nonatomic,strong) NSString * testString2;@property (nonatomic,strong) NSString * testString3;@end@implementation ViewController-(void)viewDidLoad {        [super viewDidLoad];    /**      *  定義三個測試的成員變數      */    NSString * Stringone;    NSString * Stringtwo;    NSString * Stringthree;
unsigned int count; // OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount) // 下面是官方的注釋,大概翻譯; /** 描述一個類的屬性列表 * Describes the properties declared by a class. * * @param cls The class you want to inspect. 參數 outCount這個參數是返回了你這個屬性列表數組的長度 * @param outCount On return, contains the length of the returned array. * If \e outCount is \c NULL, the length is not returned. * 這個方法返回的是一個屬性的列表數組 * @return An array of pointers of type \c objc_property_t describing the properties * declared by the class. Any properties declared by superclasses are not included. 返回的數組包含的 outCount 指標用NULL結尾的,必須釋放這個array用free() * The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free(). * * If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0. */ // 這裡傳的是 &count ,是 count 的地址,outCount是返回的數組的長度的指標,傳值就傳變數的地址,系統就把長度返回給了這個變數 // 屬性 objc_property_t * propertyList = class_copyPropertyList([self class],&count); for (unsigned int i = 0; i<count; i++) { // objc_property_t property // (nonnull const char *) const char * property = property_getName(propertyList[i]); NSLog(@"property %@",[NSString stringWithUTF8String:property]); } /** * 列印 2016-08-29 11:37:03.302 RunTimeTest[10078:132260] property testString1 2016-08-29 11:37:03.303 RunTimeTest[10078:132260] property testString2 2016-08-29 11:37:03.303 RunTimeTest[10078:132260] property testString3 */ // 方法 Method * methontList = class_copyMethodList([self class], &count); for (unsigned int i = 0 ; i<count; i++) { Method methond = methontList[i]; NSLog(@"methond %@",NSStringFromSelector(method_getName(methond))); } /** * 2016-08-29 14:01:30.458 RunTimeTest[16581:201546] methond ClassTestone 2016-08-29 14:01:30.458 RunTimeTest[16581:201546] methond ClassTesttwo 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond ClassTesthree 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond testString1 // testString1 get方法 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond setTestString1: 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond testString2 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond setTestString2: 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond testString3 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond setTestString3: 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond .cxx_destruct // 2016-08-29 14:01:30.459 RunTimeTest[16581:201546] methond didReceiveMemoryWarning 2016-08-29 14:01:30.460 RunTimeTest[16581:201546] methond viewDidLoad */ // 成員變數 Ivar * ivarList = class_copyIvarList([self class], &count); for (unsigned int i =0 ; i<count; i++) { Ivar ivar = ivarList[i]; const char *ivarName = ivar_getName(ivar); NSLog(@"Ivar %@",[NSString stringWithUTF8String:ivarName]); } /** * 2016-08-29 14:12:17.750 RunTimeTest[17233:209405] Ivar _testString1 2016-08-29 14:12:17.751 RunTimeTest[17233:209405] Ivar _testString2 2016-08-29 14:12:17.751 RunTimeTest[17233:209405] Ivar _testString3 */ __unsafe_unretained Protocol **protocolListm = class_copyProtocolList([self class], &count); for (unsigned int i =0 ; i<count; i++) { Protocol * myprotocal = protocolListm[i]; const char * protocalname = property_getName((__bridge objc_property_t)(myprotocal)); NSLog(@"protocal %@",[NSString stringWithUTF8String:protocalname]); } // Do any additional setup after loading the view, typically from a nib.}/** * 定義三個測試的方法 */-(void)ClassTestone{ NSLog(@"i am the viewcontroller methond");}-(void)ClassTesttwo{ }-(void)ClassTesthree{}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end

還有許多:

    其實細說這塊的只是還有很多,像方法交換 、動態添加方法 、攔截調用等等等,但這個不能亂吹,我項目中暫時也沒用過,以後可能會用到吧,現在有導覽列漸層這樣的效果,把代碼給出來!

給UINavigationBar添加一個類別:

#import <objc/runtime.h>#import "UINavigationBar+Background.h"@implementation UINavigationBar (Background)// 給UINavigationBar添加動態屬性static char BackgroundKey;-(UIView *) BackgroundView{    return objc_getAssociatedObject(self, &overlayKey);}-(void)setOverlay:(UIView *) BackgroundView{    objc_setAssociatedObject(self, &BackgroundKey, BackgroundView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (void)NASetBackgroundColor:(UIColor *)backgroundColor{        if (!self. BackgroundView) {                [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];        self. BackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, CGRectGetHeight(self.bounds) + 20)]; // 比導航高二十,遮住狀態列        self. BackgroundView.userInteractionEnabled = NO;        self. BackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;        // 給導航添加一個運行時屬性.uiview類型。。放置在導航的最上面        [self insertSubview:self. BackgroundView atIndex:0];    }
self. BackgroundView.backgroundColor = backgroundColor;}
-(void)cnReset{ [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; [self. BackgroundView removeFromSuperview]; self. BackgroundView = nil; }
@end

然後在 UIScrollViewDelegate 的代理方法裡面:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { // 本質是讓導覽列添加的BackgroundView屬性根據你的scrollView的滑動範圍改變顏色 [self.navigationController.navigationBar NASetBackgroundColor:[color colorWithAlphaComponent:alpha]];  }

這是在網上看到的一個效果,就是這種導覽列的漸層:

 

iOS RunTime你知道了總得用一下

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.