iOS 小知識(shí)總結(jié)

1.避免循環(huán)引用

  • 如果【block內(nèi)部】使用【外部聲明的強(qiáng)引用】訪問(wèn)【對(duì)象A】, 那么【block內(nèi)部】會(huì)自動(dòng)產(chǎn)生一個(gè)【強(qiáng)引用】指向【對(duì)象A】

  • 如果【block內(nèi)部】使用【外部聲明的弱引用】訪問(wèn)【對(duì)象A】, 那么【block內(nèi)部】會(huì)自動(dòng)產(chǎn)生一個(gè)【弱引用】指向【對(duì)象A】
    __weak typeof(self) weakSelf = self;
    myObj.myBlock = ^{
    __strong typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
    else {
    }
    };
    2.建議書(shū)寫(xiě)枚舉模仿蘋(píng)果
    // 推薦寫(xiě)法
    typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal = 0,
    UIControlStateHighlighted = 1 << 0,
    UIControlStateDisabled = 1 << 1,
    };/
    3.凡是要求子類(lèi)重寫(xiě)父類(lèi)的方法必須先調(diào)用父類(lèi)的這個(gè)方法進(jìn)行初始化操作
    // 注意:父類(lèi)中的方法加NS_REQUIRES_SUPER,子類(lèi)重寫(xiě)才有警告提示
    - (void)prepare NS_REQUIRES_SUPER;
    4.判斷if書(shū)寫(xiě)方式
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    if (indexPath.row == 0) return 44;
    if (indexPath.row == 1) return 80;
    if (indexPath.row == 2) return 50;
    return 44;
    }
    5.建議加載xib,xib名稱(chēng)用NSStringFromClass(),避免書(shū)寫(xiě)錯(cuò)誤
    // 推薦寫(xiě)法
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([DXRecommendTagVCell class]) bundle:nil] forCellReuseIdentifier:ID];
    6.如果聲明的屬性,只想使用的get方法,不使用set方法,并且不想讓外界更改這個(gè)屬性的值,那么建議在括號(hào)里面加readonly。如果屬性是BOOL類(lèi)型,建議在括號(hào)中重寫(xiě)get方法名稱(chēng),以提高可讀性示例:
    @property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow;
    7.從系統(tǒng)相冊(cè)中取照片之前,應(yīng)該判斷系統(tǒng)相冊(cè)是否可用,如果從相機(jī)中拍照獲取,要判斷相機(jī)是否可用
    // 判斷相冊(cè)是否可以打開(kāi)
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;

    // 判斷相機(jī)是否可以打開(kāi)
     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return;
    

8.在導(dǎo)航控制中,或它的子控制器,設(shè)置導(dǎo)航欄的標(biāo)題應(yīng)該用self.navigationItem.title = @“標(biāo)題”而不建議self.title = @“標(biāo)題”;

 9.給cell設(shè)置分割線,建議用setFrame:通過(guò)設(shè)置它高度,設(shè)置分割線,而不推薦用給cell底部添加一個(gè)高度的UIView,這樣做增加了一個(gè)控件,從性能上來(lái)講,不如用setFrame設(shè)置高度

10.POST請(qǐng)求參數(shù)字典的寫(xiě)法,這樣比較裝逼~
// NSDictionaryOfVariableBindings這個(gè)宏生成一個(gè)字典,這個(gè)宏可以生成一個(gè)變量名到變量值映射的Dictionary,比如:
NSNumber * packId=@(2);
NSNumber *userId=@(22);
NSNumber *proxyType=@(2);
NSDictionary *param=NSDictionaryOfVariableBindings(packId,userId,proxyType);
11.去掉cell的分割線左側(cè)15的空隙
- (void)awakeFromNib {
self.separatorInset = UIEdgeInsetsZero;
self.layoutMargins = UIEdgeInsetsZero;
self.preservesSuperviewLayoutMargins = NO;
}
12.手機(jī)振動(dòng)
- (void)vibrate {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
13.定義函數(shù)時(shí),希望子類(lèi)override該方法時(shí)候,必須調(diào)用super,否則編譯器直接報(bào)錯(cuò)。
- (void)fooWithNothing attribute((objc_requires_super));
14.誤刪系統(tǒng)sdk頭文件的解決辦法
在終端中輸入:
$ cd ~/Library/Developer/Xcode/DerivedData/ModuleCache/
$ rm -rf *
15.NS_ASSUME_NONNULL_BEGIN && NS_ASSUME_NONNULL_END

  • __nullable指代對(duì)象可以為NULL或者為NIL
  • __nonnull指代對(duì)象不能為null
    當(dāng)我們不遵循這一規(guī)則時(shí),編譯器就會(huì)給出警告。
    - (id)itemWithName:(NSString * __nonnull)name;
    - (nullable id)itemWithName:(NSString * nonnull)name
    如果需要每個(gè)屬性或每個(gè)方法都去指定nonnull和nullable,是一件非常繁瑣的事。蘋(píng)果為了減輕我們的工作量,專(zhuān)門(mén)提供了兩個(gè)宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在這兩個(gè)宏之間的代碼,所有簡(jiǎn)單指針對(duì)象都被假定為nonnull,因此我們只需要去指定那些nullable的指針。如下代碼所示:
    NS_ASSUME_NONNULL_BEGIN
    @interface TestNullabilityClass ()
    @property (nonatomic, copy) NSArray * items;
    - (id)itemWithName:(nullable NSString *)name;
    @end
    NS_ASSUME_NONNULL_END
    16.UIKIT_EXTERN extern這個(gè)是定義字符串 變量 比#define更加的高效 .但是UIKIT_EXTERN是根據(jù)是否是C語(yǔ)言宏定義,根據(jù)語(yǔ)言區(qū)分 ,比extern更加的高效
    UIKIT_EXTERN NSString *const UIApplicationInvalidInterfaceOrientationException NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
    17.NS_EXTENSION_UNAVAILABLE_IOS
    標(biāo)記IOS插件不能使用這些API,后面有一個(gè)參數(shù),可以作為提示,用什么API替換
    + (UIApplication *)sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
    18.__kindof

__kindof 這修飾符還是很實(shí)用的,解決了一個(gè)長(zhǎng)期以來(lái)的小痛點(diǎn),拿原來(lái)的 UITableView 的這個(gè)方法來(lái)說(shuō):
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
既明確表明了返回值,又讓使用者不必寫(xiě)強(qiáng)轉(zhuǎn)。
19.UITableView的plain樣式下,取消區(qū)頭停滯效果

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView
       {
        CGFloat sectionHeaderHeight = sectionHead.height;
        if (scrollView.contentOffset.y=0)
        {
            scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
        }
        else if(scrollView.contentOffset.y>=sectionHeaderHeight)
       {
          scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0,    0, 0);
       }
      }

20.取圖片某一像素點(diǎn)的顏色 在UIImage的分類(lèi)中

       - (UIColor *)colorAtPixel:(CGPoint)point
        {
             if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point))
          {
             return nil;
           }

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        int bytesPerPixel = 4;
        int bytesPerRow = bytesPerPixel * 1;
        NSUInteger bitsPerComponent = 8;
        unsigned char pixelData[4] = {0, 0, 0, 0};

        CGContextRef context = CGBitmapContextCreate(pixelData,
                                             1,
                                             1,
                                             bitsPerComponent,
                                             bytesPerRow,
                                             colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
      CGColorSpaceRelease(colorSpace);
      CGContextSetBlendMode(context, kCGBlendModeCopy);

      CGContextTranslateCTM(context, -point.x, point.y - self.size.height);
      CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), self.CGImage);
      CGContextRelease(context);

      CGFloat red   = (CGFloat)pixelData[0] / 255.0f;
      CGFloat green = (CGFloat)pixelData[1] / 255.0f;
      CGFloat blue  = (CGFloat)pixelData[2] / 255.0f;
      CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;

      return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
      }

21.禁止鎖屏

      [UIApplication sharedApplication].idleTimerDisabled = YES;
      或
      [[UIApplication sharedApplication] setIdleTimerDisabled:YES];

22.字符串按多個(gè)符號(hào)分割



23.iOS跳轉(zhuǎn)到App Store下載應(yīng)用評(píng)分

       [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APPID"]];

24.NSArray 快速求總和 最大值 最小值 和 平均值

      NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
      CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
      CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
      CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
      CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
      NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min);

25.Base64編碼與NSString對(duì)象或NSData對(duì)象的轉(zhuǎn)換

      NSData *nsdata = [@"iOS Developer Tips encoded in Base64"dataUsingEncoding:NSUTF8StringEncoding];

      NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];

      NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:base64Encoded options:0];

      NSString *base64Decoded = [[NSString alloc]  initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];

26.取消UICollectionView的隱式動(dòng)畫(huà)UICollectionView在reloadItems的時(shí)候,默認(rèn)會(huì)附加一個(gè)隱式的fade動(dòng)畫(huà),有時(shí)候很討厭,尤其是當(dāng)你的cell是復(fù)合cell的情況下(比如cell使用到了UIStackView)。

      //方法一
      [UIView performWithoutAnimation:^{
       [collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
      }];

      //方法二
      [UIView animateWithDuration:0 animations:^{
       [collectionView performBatchUpdates:^{
       [collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
       } completion:nil];
      }];

27.dispatch_group的使用 主要用于多任務(wù)請(qǐng)求

      dispatch_group_t dispatchGroup = dispatch_group_create();
      dispatch_group_enter(dispatchGroup);
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"第一個(gè)請(qǐng)求完成");
      dispatch_group_leave(dispatchGroup);
      });

      dispatch_group_enter(dispatchGroup);

      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
       NSLog(@"第二個(gè)請(qǐng)求完成");
      dispatch_group_leave(dispatchGroup);
      });

      dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        NSLog(@"請(qǐng)求完成");
      });

28.獲取手機(jī)安裝的應(yīng)用

      Class c =NSClassFromString(@"LSApplicationWorkspace");
      id s = [(id)c performSelector:NSSelectorFromString(@"defaultWorkspace")];
      NSArray *array = [s performSelector:NSSelectorFromString(@"allInstalledApplications")];
      for (id item in array)
      {
       NSLog(@"%@",[item performSelector:NSSelectorFromString(@"applicationIdentifier")]);
      //NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleIdentifier")]);
      NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleVersion")]);
      NSLog(@"%@",[item performSelector:NSSelectorFromString(@"shortVersionString")]);
      }

29.應(yīng)用內(nèi)打開(kāi)系統(tǒng)設(shè)置界面

      //iOS8之后
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
      //如果App沒(méi)有添加權(quán)限,顯示的是設(shè)定界面。如果App有添加權(quán)限(例如通知),顯示的是App的設(shè)定界面。

30.navigationBar根據(jù)滑動(dòng)距離的漸變色實(shí)現(xiàn)

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView
      {
        CGFloat offsetToShow = 200.0;//滑動(dòng)多少就完全顯示
        CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
        [[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = alpha;
      }

31.AFN移除JSON中的NSNull

      AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
      response.removesKeysWithNullValues = YES;

32.UIWebView里面的圖片自適應(yīng)屏幕

      - (void)webViewDidFinishLoad:(UIWebView *)webView
       {
         NSString *js = @"function imgAutoFit() { \
         var imgs = document.getElementsByTagName('img'); \
         for (var i = 0; i ( imgs.length; ++i) { \
         var img = imgs[i]; \
          img.style.maxWidth = %f; \
        } \
       }";

      js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width - 20];

        [webView stringByEvaluatingJavaScriptFromString:js];
        [webView stringByEvaluatingJavaScriptFromString:@"imgAutoFit()"];
      }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容