1. 命名规范
使用清晰、具有描述性的命名来提高代码可读性。
// Bad
NSString *a = @"Hello";
// Good
NSString *greetingMessage = @"Hello";
2. 使用const修饰符
在不需要修改的情况下,使用const
修饰符来定义常量。
// Bad
#define PI 3.14159
// Good
const CGFloat pi = 3.14159;
3. 使用枚举
使用枚举来增强代码的可读性和可维护性。
typedef NS_ENUM(NSInteger, Fruit) {
FruitApple,
FruitBanana,
FruitOrange
};
Fruit selectedFruit = FruitApple;
4. 使用@property和@synthesize
使用@property
和@synthesize
来自动生成访问器方法,并遵循封装原则。
// .h文件
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end
// .m文件
@implementation Person
@synthesize name = _name;
@end
5. 使用instancetype返回对象
使用instancetype
关键字来返回实例化的对象,以便于子类化和链式调用。
// Bad
- (id)init {
return [[Person alloc] initWithName:@"John"];
}
// Good
- (instancetype)init {
return [[self.class alloc] initWithName:@"John"];
}
6. 使用#pragma mark
使用#pragma mark
标识符来将类的实现部分分隔成不同的部分,以提高代码的可读性。
@implementation ViewController
#pragma mark - View Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
#pragma mark - Private Methods
- (void)doSomething {
// Implementation
}
@end
7. 使用异常处理
合理使用@try
、@catch
和@finally
来处理可能出现的异常情况。
@try {
// Code that may throw an exception
}
@catch (NSException *exception) {
// Handle the exception
}
@finally {
// Always executed, whether an exception occurred or not
}
8. 使用分析工具
使用静态代码分析工具(例如clang)来捕获潜在的编码错误和内存泄漏。
9. 使用单例模式
在需要全局访问的类中使用单例模式,确保只有一个实例存在。
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static MyClass *sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
10. 使用dispatch_once创建线程安全的共享实例
+ (instancetype)sharedInstance {
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
11. 使用块(Blocks)捕获变量
void (^simpleBlock)(void) = ^{
NSLog(@"This is a block");
};
int value = 10;
void (^blockWithVariable)(void) = ^{
NSLog(@"The value is %d", value);
};
12. 避免循环引用
__weak typeof(self) weakSelf = self;
[self doSomethingWithCompletion:^{
[weakSelf handleCompletion];
}];
13. 使用NSCache管理缓存
NSCache *cache = [[NSCache alloc] init];
[cache setObject:object forKey:key];
id cachedObject = [cache objectForKey:key];
14. 使用属性修饰符限制访问权限
@property (nonatomic, strong, readonly) NSArray *items;
@property (nonatomic, assign, getter=isHidden) BOOL hidden;
15. 使用类扩展(Class Extension)隐藏私有方法和属性
@interface MyClass ()
- (void)privateMethod;
@property (nonatomic, strong) NSObject *privateProperty;
@end
16. 使用快速枚举
使用快速枚举遍历数组和字典。
NSArray *array = @[ @"Apple", @"Banana", @"Orange" ];
for (NSString *fruit in array) {
NSLog(@"Fruit: %@", fruit);
}
NSDictionary *dictionary = @{ @"Name": @"John", @"Age": @30 };
[dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
NSLog(@"%@: %@", key, value);
}];
17. 使用NSArray和NSDictionary的安全方法
NSArray *array = @[ @"Apple", @"Banana" ];
NSString *fruit = [array objectAtIndex:0];
NSString *unknownFruit = [array objectAtIndex:2]; // 崩溃
NSString *safeFruit = [array objectAtIndex:2 withDefault:@"Unknown Fruit"];
18. 使用NSPredicate进行过滤
NSArray *array = @[ @"Apple", @"Banana", @"Orange" ];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH 'A'"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
19. 使用dispatch_async执行异步任务
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// Perform background task
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI on the main thread
});
});
20. 使用NSNotification进行通知传递
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" object:nil];
21. 使用KVO观察对象属性的变化
[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"name"]) {
NSString *newName = change[NSKeyValueChangeNewKey];
NSLog(@"Name changed to: %@", newName);
}
}
22. 使用NSFileManager进行文件操作
NSString *path = @"/path/to/file.txt";
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path]) {
NSError *error = nil;
[fileManager removeItemAtPath:path error:&error];
if (error) {
NSLog(@"Error deleting file: %@", error);
}
}
23. 使用NSUserDefaults存储用户设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"John" forKey:@"UserName"];
24. 使用NSCoding进行对象序列化
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person];
Person *unarchivedPerson = [NSKeyedUnarchiver unarchiveObjectWithData:data];
25. 使用GCD进行多线程编程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Perform background task
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI on the main thread
});
});
26. 使用Core Data进行数据持久化
NSManagedObjectContext *context = [[AppDelegate sharedInstance] managedObjectContext];
NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
[person setValue:@"John" forKey:@"name"];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Error saving context: %@", error);
}
27. 使用Autolayout布局界面
UIView *redView = [[UIView alloc] init];
redView.translatesAutoresizingMaskIntoConstraints = NO;
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
// 添加约束
[redView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20].active = YES;
[redView.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20].active = YES;
[redView.widthAnchor constraintEqualToConstant:100].active = YES;
[redView.heightAnchor constraintEqualToConstant:100].active = YES;
28. 使用UICollectionView和UITableView展示集合数据
@interface MyViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate>
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSArray *dataArray;
@end
@implementation MyViewController
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
// Configure the cell
return cell;
}
@end
29. 使用Core Animation创建动画效果
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:self.imageView.layer.position];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
animation.duration = 1.0;
[self.imageView.layer addAnimation:animation forKey:@"positionAnimation"];
30. 使用适用的设计模式
根据不同的情况选择适用的设计模式,例如:单例模式、观察者模式、工厂模式等。
31. 使用弱引用避免循环引用
在block内部使用__weak
修饰的引用,避免循环引用。
__weak typeof(self) weakSelf = self;
[self doSomethingWithCompletion:^{
[weakSelf handleCompletion];
}];
32. 使用断言进行调试
NSAssert(condition, @"Assertion failed: %@", message);
NSAssert2(condition, @"Assertion failed: %@, %@", message1, message2);
33. 使用#pragma unused删除未使用的变量警告
#pragma unused(variableName)
34. 使用运行时机制进行方法交换
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
35. 使用NSOperation和NSOperationQueue管理并发任务
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
// Perform the task
}];
[queue addOperation:operation];
36. 使用Core Graphics进行绘图
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
37. 使用UIStackView布局界面
UIStackView *stackView = [[UIStackView alloc] init];
stackView.axis = UILayoutConstraintAxisVertical;
stackView.spacing = 20;
stackView.distribution = UIStackViewDistributionFillEqually;
[stackView addArrangedSubview:view1];
[stackView addArrangedSubview:view2];
[self.view addSubview:stackView];
38. 使用UIActivityIndicatorView显示加载状态
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = self.view.center;
[activityIndicator startAnimating];
[self.view addSubview:activityIndicator];
39. 使用NSRegularExpression进行正则表达式匹配
NSString *string = @"Hello World";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"Hello" options:0 error:nil];
NSTextCheckingResult *result = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
40. 使用NSURLSession发送网络请求
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"https://api.example.com/data"];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Handle the response
}] resume];
41. 使用NSXMLParser解析XML数据
@interface MyXMLParser : NSObject <NSXMLParserDelegate>
@end
@implementation MyXMLParser
- (void)parseXMLData:(NSData *)xmlData {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
parser.delegate = self;
[parser parse];
}
- (void)parser:(NSXMLParser *)parser foundElementDeclarationWithName:(NSString *)elementName model:(NSString *)model {
// Handle the element declaration
}
@end
42. 使用NSURLSessionDownloadTask下载文件
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"https://example.com/file.zip"];
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
// Handle the downloaded file
}];
[task resume];
43. 使用UIAlertController显示警告和提示框
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// Handle the OK button tap
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
44. 使用CAShapeLayer创建自定义形状
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds cornerRadius:10].CGPath;
shapeLayer.fillColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:shapeLayer];
45. 使用CGAffineTransform进行视图变换
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.transform = CGAffineTransformMakeRotation(M_PI_4);
[self.view addSubview:view];
46. 使用CoreLocation获取设备位置信息
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization]; // 请求授权
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
47. 使用外观模式简化复杂接口
@interface NotificationManager : NSObject
- (void)registerForRemoteNotifications;
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo;
@end
@implementation NotificationManager
- (void)registerForRemoteNotifications {
// Register for remote notifications
}
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo {
// Handle the received notification
}
@end
48. 使用NSKeyedArchiver进行对象序列化
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person];
Person *unarchivedPerson = [NSKeyedUnarchiver unarchiveObjectWithData:data];
49. 使用UITapGestureRecognizer添加手势识别
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGestureRecognizer:tapGesture];
- (void)handleTap:(UITapGestureRecognizer *)gesture {
CGPoint location = [gesture locationInView:self.view];
NSLog(@"Tapped at: %@", NSStringFromCGPoint(location));
}
50. 使用NSUserDefaults存储用户设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"John" forKey:@"UserName"];