修改gradle属性,加快Android studio编译速度
1.在自己项目的gradle中加入 android{ ... dexOptions{ maxProcessCount4// this is the default value javaMaxHeapSize"2g" } } 2.在项目的中修改gradle.properties org.gradle.jvmargs=-Xmx3072m over!
Tips 15 使用前缀避免明明空间冲突
Tips 16 提供“全能(designated)初始化方法”
Tips 17 实现 description 方法
description 方法,方便调试description 方法对于自定义的对象并没有输出较为有用的内容,所以可以实现这个方法方便我们显示对象debugDescription 方法(也就是在调试时 lldb 中输入 po 时调用的将会是 debugDescription),所以实现他可以帮助我们调试时获得更多的信息NSDictionary 来实现 description 方法,这样显示和输出都会比较方便,例如: // Header File
// 这里我略微修改了下原书中的示例代码
@interface EOCLocation : NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic) CGFloat latitude;
@property (nonatomic) CGFloat longitude;
@end
// 我们要是可以使用 NSLog(@"%@", eoc_location) 直接输出这个对象的经纬度(也就是所有属性)就好了,那么可以参考下面的写法实现 description 方法
@implementation EOCLocation
- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p, %@>",
[self class],
self,
@{
@"title": self.title,
@"latitude": @(self.latitude),
@"longitude": @(self.longitude),
}];
}
@end
Tips 18 尽量使用不可变对象
[object setValue:@"value" forKey:@"propertyName"] -addFriend: 和 -removeFriend: 方法来实现对 friends 集合的操作,这样保证了添加或删除盆友的操作对象是知情的。对于直接修改 friends 集合的操作对象是不知情的,这样可能会导致对象内各数据的不一致。 @interface EOCPerson : NSObject
@property (nonatomic, strong, readonly) NSSet *friends;
@end
@implementation EOCPerson {
NSMutableSet *_internalFriends;
}
- (NSSet *)friends {
return [_internalFriends copy];
}
- (void)addFriend:(EOCPerson *)person {
[_internalFriends addObject:person];
}
- (void)removeFriend:(EOCPerson *)person {
[_internalFriends removeObject:person];
}
@end
Tips 19 使用清晰而协调的命名方式
Rectangle *recgangle = new Rectangle(5.0f, 10.0f);
// 不如下面的命名方式
Rectangle *recgangle = [Rectangle initWithSize:(float)width :(float)height];
// 不如下面的命名方式
Rectangle *recgangle = [Rectangle initWithWidth:(float)width andHeight:(float)height];
Tips 20 为私有方法名加前缀
_ 下划线作为系统内部函数的开头所以我们不能使用 _ 作为私有方法的前缀(苹果的官方库也使用 _)p_ 来作为私有方法的前缀,个人建议使用开发中项目使用的前缀小写来作为类前缀,比如上文的 EOCPerson 中添加私有方法可以使用 eco_privateMethodName:,这样的前缀在第三方类库中出现重复的概率比较小Tips 21 理解 Objective-C 错误模型
-fobjc-arc-exceptions 来告诉编译器需要生成异常安全的代码,但是这样会引入一些额外代码,并且在不抛出异常时也会执行这部分代码NSError 来处理,NSError 中包含了错误处理所需的各种信息,我们自己的错误需要规划和设置好对应的 Error Domain,Error Code- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 或是输入参数返回错误 - (BOOL)doSomething:(NSError **)error Tips 22 理解 NSCopying 协议
NSCopying 接口可以让类实现拷贝(copy)方法,- (id)copyWithZone:(NSZone *)zone 中的 zone 是以前开发时使用的内存区参数,目前已经不使用了,可以不用考虑他NSMutableCopying 协议支持可变拷贝(mutableCopy)方法NSCopying 实现的都是浅拷贝,所以如果使用深拷贝,建议创建一个单独的方法来完成Tips 23 使用委托(delegate)和数据源(data source)协议进行对象间通信
UITableView,UITableViewDelegate 和 UITableViewDataSource 分别定义了如何处理事件的接口和如何提供数据的接口,实现这两个接口为 UITableView 提供交互逻辑和显示数据,UITableView 本身只负责显示获取到的数据respondsToSelector: 先查询委托对象是否实现了该方法,特别是在协议中使用 @option 关键字标注的可选方法respondsToSelector: 方法来查询是否实现,例:@interface EOCNetworkFetcher() {
struct {
unsigned int didReceiveData : 1;
unsigned int didFailWithError : 1;
unsigned int didUpdateProgressTo : 1;
} _delegateFlags;
}
@end
@implementation EOCNetworkFetcher
- (void)setDelegate:(id<EOCNetworkFetcherDelegate>)delegate {
_delegate = delegate;
_delegateFlags.didReceiveData = [delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
_delegateFlags.didFailWithError = [delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
_delegateFlags.didUpdateProgressTo = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}
@end
// 在需要调用 delegate 方法的时候
if (_delegateFlags.didUpdateProgressTo) {
[_delegate networkFetcher:self didUpdateProgressTo:currentProgress];
}
Tips 24 将类的实现代码分散到便于管理的多个 Category 中
Tips 25 总是为第三方分类的分类名称加前缀
Tips 26 勿在分类中声明属性
objc_setAssociatedObject 魔法可以用,但是这容易导致内存管理问题,因为无法使用属性记录内存管理语义,但是建议一般情况下不使用Tips 27 使用 Class-Continuation 分类,隐藏实现细节
Tips 28 通过协议提供匿名对象
@property(nonatomic, weak) id<ProtocolName> delegate; 提供匿名类型对象作为 delegate,可以隐藏类名第一章第四条中,多用类型常量,少用 #define 预处理指令中,建议大家使用类型常量而不是 #define 来定义常量,这里增加一个补充内容,swift 中,我们可以使用 struct 中的静态变量来声明常量,这样带来的一个好处是使用和分类管理非常方便
Xcode 8.0 带的 clang 4.0 后开始支持类常量,也就是定义属性的时候,可以加入 class 来修饰属性,这样这个属性是属于类的,于是乎,我们可以这样使用常量了
NSString *notificationName = XXXConstant.notificationNames.XXXUserDidLoginNotificationName;
看上去比类型常量长一些,不过似乎还算比较好看
定义的时候需要这样定义:
@interface XXXConstantNotificationNames : NSObject
@property(nonatomic, readonly) NSString *XXXUserDidLoginNotificationName;
@end
@interface XXXConstant : NSObject
@property(nonatomic, class, copy) XXXConstantNotificationNames *notificationNames;
@end
并且,类常量是不会被 synthesize 的,也就是说编译器不会自动为类常量创建相应的变量,所以在实现文件中,我们需要这么写
@implementation XXXConstantNotificationNames
- (NSString *)XXXUserDidLoginNotificationName {
return @"XXXUserDidLoginNotificationName";
}
@end
@implementation XXXConstant
static XXXConstantNotificationNames *_notificationNames = nil;
+ (void)load {
_notificationNames = [[XXXConstantNotificationNames alloc] init];
}
- (XXXConstantNotificationNames *) {
reutrn _notificationNames;
}
@end
看上去比定义一个 kXXXUserDidLoginNotificationName 字符串常量,麻烦了非常多,但是相信在项目代码量不断增加,以及工程变得越来越复杂以后,这样的做法对于代码管理上是非常有帮助的
微信关注我们
转载内容版权归作者及来源网站所有!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。
为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。
Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。
Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。