iOS知識集錦(継続的な更新)

10242 ワード

ruby.taobao.orgは更新を停止し、coapodsの子供靴を使ってruby chinaのソースに更新しました
$ gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
$ gem sources -lhttps://gems.ruby-china.org #      gems.ruby-china.org
$ gem sources -l 
*** CURRENT SOURCES ***
https://gems.ruby-china.org
#       gems.ruby-china.org
$ gem install rails

$gem install railsでこのようなエラーが発生しました.
yitudevdeiMac:~ yitudev$ gem install rails
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ dir_s_mkdir - /usr/local/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-15/2.3.0/nokogiri-1.6.8.1
yitudevdeiMac:~ yitudev$ gem install rails
Building native extensions.  This could take a while...

操作:
yitudevdeiMac:~ yitudev$ sudo gem install cocoapods-core 

さらに$gem install rails.pod setupがSettings up CocoaPods master repoに入って待機している間にダウンロード中であることを示すと、新しいターミナルウィンドウを開き、「cd~/.coapods/」コマンドラインを入力してcocoapodsフォルダにジャンプし、「du-sh*」を実行してダウンロード中のフォルダのサイズを表示することができます.CocoaPodsの簡単なクイックインストール方法(Settings up CocoaPods master repoが動かないのは、タオバオのミラーリングが使えなくなったからです)
  • CocoaPodsを使用してサードパーティクラスライブラリを追加します.pod installを実行してもpod updateを実行してもAnalyzing dependenciesに引っかかっています.なぜなら、以上の2つのコマンドを実行するとCocoaPodsのspec倉庫をアップグレードし、パラメータを追加するとこのステップを省略することができ、速度が大幅に向上するからです.(最近installとupdateが行われており、--no-repo-updateを付けても死ぬことがある)
  • pod install --verbose --no-repo-update
    pod update --verbose --no-repo-update
    

    NULL、nil、Nil、NSNullの違い
    ひょうしき

    意味
    NULL
    (void *)0
    Cポインタの文字列空値
    nil
    (id)0
    Objective-Cオブジェクトの文字列の空の値
    Nil
    (Class)0
    Objective-Cクラスの文字列空値
    NSNull
    [NSNull null]
    空の値を表すObjective-Cオブジェクト
  • NULLは一般的にCポインタの空の値を表すために使用され、例えば:
  • int *pointerToInt = NULL;
    char *pointerToChar = NULL;
    struct TreeNode *rootNode = NULL;
    
  • nil:
  • NSString *someString = nil;
    NSURL *someURL = nil;
    id someObject = nil;
    if (anotherObject == nil) 
    
  • Nil:
  • Class someClass = Nil;
    Class anotherClass = [NSString class];
    
  • NSNullはObjective-Cオブジェクトであり、空の値を表すクラスであり、集合オブジェクトに空の占有オブジェクトを保存するために一般的に使用される+[NSNull null]という単一の方法しかありません.
  • //   NSArray     nil  ,               ,  NSArray     nil      ,nil          。
    NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil];
    
    //      
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:nil forKey:@"someKey"];
    
    //      
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:[NSNull null] forKey:@"someKey"];
    

    遅延実行関数のキャンセル
  • 法一:performSelector
  • - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;  
    - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;  
    //            
    + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument; 
    //   performSelector            
    + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget; 
    
  • 法2:タイマ
  • の作成
    //       time-   ,    fire     ,        NSInvocation 
    + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
    //       time-   ,    fire     
    + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
    //       scheduled-   ,     fire     ,        NSInvocation 
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
    //       scheduled-   ,     fire     
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
    //           ,           
    - (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(id)ui repeats:(BOOL)rep;
    //      
    - (void)fire;
    //       ,           
    - (void)invalidate;
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(prtintMyWords:) userInfo:@{@"words":@"hello world"} repeats:NO];
    [self.timer invalidate];
    
  • 法3:GCDを使用してGCDの遅延実行をキャンセルする方法はまだ分からないので、Dispatch-Cancel
  • を参照してください.
    //       ,       ,3    。 3        ,               
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 3.0*NSEC_PER_SEC);
    //       
    dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       [self printString:@"hello world"];
    });
    
  • 注意:1、performSelectorおよびscheduledTimerWithTimeIntervalメソッドはrunloopに基づいています.アプリケーションが起動すると、システムはプライマリスレッドを開き、プライマリスレッドのrunloop、すなわちrunをアクティブにし、プライマリスレッドのrunloopは停止しないことを知っています.したがって、この2つの方法がプライマリスレッドで正常に呼び出される場合.しかし、状況は往々にしてそうではない.実際の符号化では,我々のより多くの論理はサブスレッドにおいて実行される.サブスレッドのrunloopはデフォルトで閉じられています.このときrunloopを手動でアクティブにしないと、performSelectorとscheduledTimerWithTimeIntervalの呼び出しは無効になります.2、NSTimer、performSelectorの作成と取り消しは同じスレッドで行う必要があります.3、timerがscheduleされると、timerはtargetオブジェクトを持ち、NSRunLoopオブジェクトはtimerを持つ.invalidateが呼び出されると、NSRunLoopオブジェクトはtimerの保有を解放し、timerはtargetの保有を解放します.それ以外に、timerのtargetに対する所有を解放する方法はありません.メモリ漏洩を解決するにはtimerを取り消す必要があります.取り消さないとtargetオブジェクトは解放されません.4、dispatch_を使うとafter、システムはスレッドレベルの論理を処理してくれます.そうすれば、システムがスレッドに対して行った最適化をより容易に楽しむことができます.それ以外にrunloopの問題に関心を持つ必要はありません.また,呼び出されたオブジェクトも強制的に保持されず,上述したメモリの問題もなくなった.もちろん、blockは入力されたオブジェクトを持つことに注意する必要がありますが、これはweakselfで解決できます.従って、この遅延動作方式では、dispatch_を用いるafterのほうがいいです.

  • バージョン番号の制御方法
    GNUスタイルのバージョン番号管理ポリシー:一般的なバージョン番号は、「マスターバージョン番号.サブバージョン番号.修正バージョン番号」の3つの部分に分けられ、簡単で直感的で明確です.1、プロジェクトの初期バージョンの場合、バージョン番号は0.1または0.1.0であってもよいし、1.0または1.0.0(例えば:1.0.0)であってもよい2、プロジェクトがローカル修正またはバグ修正を行った場合、メインバージョン番号とサブバージョン番号はいずれも変わらず、修正バージョン番号に1(例えば:1.0.1)3を加え、プロジェクトが元の基礎の上で一部の機能を追加した場合、メインバージョン番号は変わらず、サブバージョン番号に1を加え、修正バージョン番号は0(例えば1.1.0)4にリセットされ、重大な修正が行われたり、局所的な修正が蓄積されたりして、プロジェクト全体がグローバルに変化した場合、主バージョン番号に1(例えば2.0.0)5を加え、また、コンパイルバージョン番号は一般的にコンパイラがコンパイル中に自動的に生成され、そのフォーマットのみを定義し、人為的な制御を行わない.
    直接呼び出し方法とperformSelector呼び出しの違い
    1、2つの方法で実行される効果は、メッセージの送信と等価である.2、performSelectorは実行時に確定していないメッセージを送信することを許可する.すなわち、このメッセージが正しい受信者に転送され、最後の受信者によって識別される限り、正しく動作することができる.そうでない場合、実行時に「unrecognized selector sent to instance」とエラーが発生します.このメソッドが実装されていない場合は、実行時にのみエラーが報告され、コンパイルフェーズでは見つかりません.3、Obejct-Cの動的特性は、実行時にクラスにメソッドを追加することを許可し、この場合はperformSelectorを使用する必要があります.では、実行中にエラーが発生しないように、performSelectorを使用する前に、必ず次のようなチェック方法で判断してください.私たちは一般的に無視してこの方法で判断します.
    - (BOOL)respondsToSelector:(SEL)aSelector;
    

    #pragma処理防止コンパイラ警告
  • まず#pragmaは本質的に宣言であり、よく使われる機能は注釈であり、特にCodeにセグメント注釈を与える.また、コンパイラの警告を処理するもう一つの強力な機能がありますが、前の機能ほど使用されていません.clang diagnosticは#pragmaの最初の一般的なコマンドです:
  • #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-    " 
    //       
    #pragma clang diagnostic pop
    
  • よくある使い方1、方法廃棄警報
  • #pragma clang diagnostic push 
    #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
    [TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]]; 
    #pragma clang diagnostic pop
    

    2、互換性のないポインタタイプ
    #pragma clang diagnostic push 
    #pragma clang diagnostic ignored "-Wincompatible-pointer-types"  
    // 
    #pragma clang diagnostic pop
    

    3、循環参照
    #pragma clang diagnostic push 
    #pragma clang diagnostic ignored "-Warc-retain-cycles"  
      self.completionBlock = ^ {
         ... 
      }; 
    #pragma clang diagnostic pop
    

    4、変数を使用しない
    #pragma clang diagnostic push 
    #pragma clang diagnostic ignored "-Wunused-variable"  
    int a; 
    #pragma clang diagnostic pop
    

    5、パラメータが固定されていない場合:DKNightVersionを例に
    DKImagePicker DKImagePickerWithNames(NSString *normalName, ...) {
        NSArray *themes = [DKColorTable sharedColorTable].themes;
        NSMutableArray *names = [[NSMutableArray alloc] initWithCapacity:themes.count];
        [names addObject:normalName];
        NSUInteger num_args = themes.count - 1;
        va_list names_list;
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wvarargs"
        va_start(names_list, num_args);
    #pragma clang diagnostic pop
        for (NSUInteger i = 0; i < num_args; i++) {
            NSString *name = va_arg(names_list, NSString *);
            [names addObject:name];
        }
        va_end(names_list);
    
        return [DKImage pickerWithNames:names];
    }
    

    va_arg(va_list ap,type)、パラメータapはまずマクロva_startまたはva_copyは初期化されますが、マクロvaでなければなりません.end呼び出しの前に使用します.毎回va_を呼び出すargはap値を変更し、後続のパラメータ値を順次追加できるようにします.パラメータtypeはタイプ名であり、type*でそのタイプのポインタタイプを得ることができます.typeが空の場合、またはtypeが実際のパラメータと一致しない場合、このマクロの動作は、以下の2つの場合を除いて定義されません.用法:(1)まず関数にVAを定義するパラメータを指すポインタであるLIST型の変数.(2)そしてVA_STARTマクロ初期化定義済みVA_LIST変数;(3)そしてVA_ARGは可変パラメータを返し、VA_ARGの2番目のパラメータは、返すパラメータのタイプです(関数に複数の可変パラメータがある場合は、VA_ARGを順次呼び出して各パラメータを取得します).(4)最後にVA_を使うENDマクロは、可変パラメータの取得を終了する.
    オブジェクト内でインスタンス変数にできるだけ直接アクセスする
  • オブジェクト内部でデータを読み込む場合は、インスタンス変数で直接読むべきであり、データを書き込む場合は属性で書くべきである.
  • 初期化およびdeallocメソッドでは、常にインスタンス変数によってデータを読み書きする必要があります.

  • メッセージング、転送メカニズム
  • objc_msgSendは,受信者と選択子のタイプに応じて適切なメソッドを呼び出す.このメソッドは、受信者が属するクラスで「メソッドリスト」を検索し、サブ名を選択したメソッドが見つかると、実際の現代コードにジャンプする必要があります.見つからない場合は、継承システムに沿って上を探し続け、適切な方法を見つけてからジャンプします.最終的に適切な方法が見つからない場合は、メッセージ転送操作を実行します.
  • メッセージ転送は2つのステップに分けられる:1、受信者が属するクラスに問い合わせ、メソッドを動的に追加して、現在の「未知の選択子」を処理できるかどうかを確認し、これを「動的メソッド解析」と呼ぶ.2、「完全なメッセージ転送メカニズム」に関して、2つのステップに分けられる:受信者は他のオブジェクトがこのメッセージを処理できるかどうかを見て、もしあれば、運行期間システムはメッセージをそのオブジェクトに転送して、メッセージ転送は終了する.「バックアップの受信者」がいない場合、完全なメッセージ転送メカニズムが起動され、ランタイムシステムはメッセージに関するすべての詳細をNSInvocationにカプセル化し、受信者に最後の機会を与え、現在処理されていないメッセージを解決するようにします.

  • isMemberOfClass:isKindOfClass:と区別
  • 「isMemberOfClass:」は、オブジェクトが特定のクラスのインスタンスであるか否かを判断することができる.
  • 「isKindOfClass:」は、オブジェクトがクラスまたはその派生クラスのインスタンスであるか否かを判断することができる.
  • は、特定のオブジェクトがメッセージ転送機能を実現する可能性があるため、クラスオブジェクトを直接比較するのではなく、タイプ情報照会方法を使用してオブジェクトタイプを決定する.