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()"];
}
