iOSÈçºÎ½øÐÐÓÅ»¯ÏîÄ¿£¿
ÔÚÏîĿҵÎñÇ÷ÓÚÎȶ¨µÄʱºò£¬¿ª·¢Íêµü´úÐèÇóºó£¬ÎÒÃÇ¿ÉÄÜ»áÎÞËùÊÊ´Ó£¬½øÈëÒ»¶Î¿Õ°×ÆÚ£¬µ«ÊǶÔÓÚ¹¥³ÇʨÀ´ËµÏÐϾ²»ÊǼþºÃÊ£¬ËùÒÔÎÒÃÇ¿ÉÄÜ×ÜÏëѧµãʲô£¬È´ÓÖûÓÐÍ·Ð÷¡£Õâ¸öʱºòÎÒÃǾͿÉÒÔ¿¼ÂÇÍêÉÆºÍÓÅ»¯ÎÒÃǵÄÏîÄ¿ÁË¡£
1. ½á¹¹Óë¼Ü¹¹
1.1 ½á¹¹
ÕâÀï˵µÄ½á¹¹´ó¸ÅÓÐÁ½µã£º1.ÎļþĿ¼·ÖÀà 2.µÚÈý·½¿â¹ÜÀí
1.1.1 ÎļþĿ¼·ÖÀà
ΪÁË·½±ã¹ÜÀí£¬×îºÃ½«XcodeÖеÄÏîĿչʾĿ¼Óëʵ¼ÊµÄ´æ´¢Ä¿Â¼±£³ÖÒ»ÖÂ
´ËÍ⣬һ°ã°´ÒµÎñÄ£¿é·ÖÀà,Ò»¼¶Ä¿Â¼¿ÉÒÔ°´ÕÕMVC¸ñʽ£¬Ò²¿ÉÒÔ°´ÕÕÒµÎñÄ£¿é»®·Ö
ÓÃ×îÆÕ±éµÄModel View Controller¼Ü¹¹¾ÙÀý
ÒÔÒ»¸ö»ù´¡µÄµçÉÌÏîÄ¿À´½âÊÍ£¬4¸ötabbarItem¶ÔÓ¦×ÅËÄ´óÄ£¿é£¬Ê×Ò³¡¢·ÖÀà¡¢¹ºÎï³µ¡¢¸öÈËÖÐÐÄ£¬ÍùÏÂÿ¸ö»¹¿ÉÒÔϸ·ÖΪMVC+Session²ã
°´ÏîÄ¿¼Ü¹¹À´·Ö
×îÍâ²ãΪModel¡¢View¡¢Controller¡¢Session²ã,ÄÚ²¿²ÅÊÇÒµÎñÄ£¿é
ÕâÒ»¿éÎÞÐè¶àÑÔ£¬Á½ÕßÅäºÏʹÓü´¿É
1.1.2 µÚÈý·½¿â
¸öÈ˽¨Ò飺ʱ¼äÔÊÐíµÄ»°×Ô¼º¶àÔìÔìÂÖ×Ó£¬·çÏտɿأ¬ºÃά»¤
Èç·Ç±ØÒª£¬¾¡Á¿²»ÒªÖ±½ÓʹÓÃÒѾ±àÒëºÃµÄÈý·½¿â(framework/.a)£¬×îºÃ×Ô¼ºÈ¥±àÒëÈý·½¿â(°²È«ÒªÇó)
¹ÜÀí·½ÃæÓÐÈýÖÖ·½Ê½£º
ÊÖ¶¯¹ÜÀí
ÊÖ¶¯Î¬»¤¸÷ÖÖµÚÈý·½¿â£¬ÊʺÏÓÚÒѾÇ÷ÓÚÎȶ¨¡¢¼«ÉÙBugµÄÈý·½¿â
CocoaPods
Carthage
ÕâÀï¸üÍÆ¼öʹÓÃCarthage,ÒòΪËü¶ÔÏîÄ¿µÄÇÖÈëÐÔ×îС£¬¶øÇÒÊÇÈ¥ÖÐÐÄ»¯¹ÜÀí£¬²»ÐèÒªµÈ´ýÂþ³¤µÄpod
update / install¹ý³Ì.²»¹ý¸÷Óи÷µÄºÃ´¦,ʹÓÃCocoaPods¼òµ¥´Ö±©,»ù±¾²»ÐèÒª¶îÍâÉèÖÃʲô,¿´×Ô¼ºÐèÇó°É
1.2 ÏîÄ¿¼Ü¹¹
ÏîÄ¿Âß¼»ù±¾¶¼Î§ÈÆÁËÒ»ÌõÖ÷Ïßʱ£¬ÎÒÃDzÉÓÃMVCÒѾ¿ÉÒԺܺõÄÂú×ãÎÒÃǵÄÐèÇ󣬵«Êǵ±ÒµÎñÂß¼ÈÕ½¥¸´ÔÓµÄʱºò£¬ÎÒÃǵ¥´¿µÄ²ÉÓÃModel
View ControllerÕâÖÖ±à³ÌģʽÒѾ²»ÄܺܺõĽ«ÒµÎñÂß¼Óë´úÂë·ÖÀ뿪£¬Ò²¾ÍÊǽâñîDecouple.
ΪÁ˸üºÃµÄ½«ViewController½âñ²úÉúÁËModel View ViewModelÕâÖÖ±à³Ìģʽ£¬ViewModel²ãÆäʵ×öÁËÒ»²ãModelÓëViewControllerÖмäµÄÇŽӣ¬ÓÐÀûÓбף¬¸Ãģʽ»á²úÉúºÜ¶à½ºË®´úÂ룬µ«ÊÇÅäºÏÏìӦʽ±à³Ì¿ò¼Ü(Èç
ReactiveCocoa»òÕßRxSwift),¿ÉÒÔ×öµ½×î´ó³Ì¶ÈµÄ½âñî¡££¬ÊʺÏÓë×Ô¼ºÊµ¼ÊÏîĿҵÎñ¸´Ôӳ̶ȵÄģʽ²ÅÊǺõıà³Ìģʽ¡£
ÒýÉê : <¹ØÓÚ×é¼þ»¯±à³Ì>
Èç¹ûÏîĿҵÎñºÜ¸´ÔÓ¡¢ºÜ¶àÒµÎñ×é¼þ¶¼Í¨Ó㬿ÉÒÔ²ÉÓÃ×é¼þ»¯±à³Ì£¬³£ÓõÄÒ»ÖÖ¾ÍÊDzÉÓÃCocoaPods½«ÏîĿҵÎñÄ£¿é·Ö²ð³É¸÷ÖÖpod¿â£¬Ê¹ÓÃʲôģ¿éÖ±½Ó¼¯³É¾ÍºÃ,ÔÙÅäºÏMVVMºÍÏìӦʽ±à³Ì¿ò¼Ü(Èç
ReactiveCocoa»òÕßRxSwift),¿ÉÒÔ×öµ½×î´ó³Ì¶ÈµÄ½âñî¡£
2. ±ÀÀ£&ÐÔÄܵ÷ÓÅ
µ±ÏîÄ¿ÒѾÍê³ÉÒµÎñÄ£¿éÉÏÏߺó£¬ÎÒÃǾͿÉÒÔ¿ªÊ¼¿¼ÂǹØÓÚÈçºÎÌá¸ßAppµÄÓû§ÌåÑ飬¾ÙÀýһϼ¸¸öÎÊÌ⣺
1. ´úÂë¹æ·¶£¬¶¨ÆÚcode reviewÁËÂð
2. ¸´ÔÓÁбíµÄ¹ö¶¯Ê±FPS¿ÉÒÔ±£³ÖÔÚ60Ö¡×óÓÒÂð£¿
3. Ò³Ãæ¼ÓÔØäÖȾµÄºÄʱÄܲ»ÄܽøÒ»²½¼õС£¿
4. ÍøÂ绺´æÓÐ×öÂð£¬UIWebView / WKWebViewµÄ³£Óþ²Ì¬×ÊÔ´×ö»º´æÁËÂð
5. AppµÄÆô¶¯Ê±¼ä¿ÉÒÔÔÚ±£³Ö×îСҵÎñÂß¼µÄͬʱÔÙ¼õСһµãÂð£¿
2.1 UITest & UnitTest
µ±¿ª·¢ÍêÐÂÐèÇóµÄʱºò£¬ÔÚÌá²â֮ǰÎÒÃÇ×îºÃ±àдÏÂUITestºÍUnitTest,¸²¸ÇÖ÷ÒµÎñÁ÷³Ì¼´¿É£¬¿ÉÒÔÌá¸ßÎÒÃǵÄÌá²âÖÊÁ¿£¬¼õСһЩ¿É¼ûµÄBug£¬ÔÙ¼ÓÉÏðÑÌÓÃÀý,×î´ó³Ì¶ÈÉÏÌá¸ßÎÒÃÇÌá²âµÄÖÊÁ¿(³ÉΪKPIÖ®Íõ
- ????)£¬¶øÇÒÉÏÏßÖ®ºóÕâЩµ¥Ôª²âÊÔºÍUITest×é¼þµÄ½Å±¾¿ÉÒÔÅäºÏ×Ô¶¯»¯²âÊÔ¶¨ÆÚ½øÐлعé²âÊÔ£¬Ìá¸ßAppµÄÖÊÁ¿£¬¼õÉÙ±ÀÀ£ÂÊ
2.2 NullSafe
¾ø´ó¶àÊýÇé¿öÏ£¬ÎÒÃÇÏòNSNull¶ÔÏó·¢ËÍÏûÏ¢£¬¶¼»á²úÉú±ÀÀ££¬NSNull¶ÔÏó³£¼ûÓÚºǫ́·µ»ØÊý¾ÝÖпÉÄÜ»áÓÐnull×ֶΣ¬ºÜ¶àJSON¿â¶¼»áת³ÉNSNull¶ÔÏó£¬ÈçÏÂÇé¿ö¾Í»á²úÉú±ÀÀ££º
id obj = [NSNull
null];
NSLog(@"%@", [obj stringValue]); |
µ«ÊÇÏònil¶ÔÏó·¢ËÍÏûÏ¢Ôò²»»á²úÉú±ÀÀ££¬ÕâЩ¿ÉÒԲο¼NullSafeÖеĴ¦Àí·½·¨£¬ÖØÐ´
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelectorºÍ-
(void)forwardInvocation:(NSInvocation *)anInvocationÕâÁ½¸ö·½·¨½«Ã»ÄÜÁ¦´¦ÀíÏûÏ¢µÄ·½·¨Ç©Ãûת·¢¸ønil¶ÔÏóÔò²»»á²úÉú±ÀÀ£
´ËÍ⣬³£¼ûµÄ±ÀÀ£±ÈÈ磬NSArrayȡֵԽ½ç£¬NSDictionary´«ÁËnil¶ÔÏó£¬ÕâЩÎÊÌâ²úÉúµÄ±ÀÀ£¿ÉÒÔʹÓÃRuntimeÖеÄMethod
Swizzle,½«ÔÉúµÄ·½·¨hookµô£¬ÈçÏ£º
@implementation
NSMutableDictionary (NullSafe)
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
Class class = [self class];
Method originalMethod = class_getInstanceMethod(class,
origSelector);
Method swizzledMethod = class_getInstanceMethod(class,
newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod,
swizzledMethod);
}
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
id obj = [[self alloc] init];
[obj swizzleMethod:@selector(setObject:forKey:)
withMethod:@selector(safe_setObject:forKey:)];
});
}
- (void)safe_setObject:(id)value forKey:(NSString
*)key {
if (value) {
[self safe_setObject:value forKey:key];
}else {
NullSafeLogFormatter(@"[NSMutableDictionary
setObject: forKey:], Object cannot be nil")
}
}
@end |
ÕâÖÖ½â¾ö·½·¨¿ÉÒÔ±ÜÃâÖîÈçÊý×éȡֵԽ½ç¡¢×ֵ䴫¿ÕÖµ¡¢removeObjectAtIndexµÈ´íÎó£¬ÈçϵıÀÀ£¾Í¿ÉÒÔ±ÜÃ⣺
id obj = nil;
NSMutableDictionary *m_dict = [NSMutableDictionary
dictionary];
[dict setObject:obj forKey:@"666"] |
2.2 ¼à¿ØÏµÍ³
Ŀǰ´ó¶àÊýApp¶¼¼¯³ÉÁ˵ÚÈý·½Í³¼Æ¿â£¬³£¼ûµÄ±ÈÈçÌÚѶµÄBugly¡¢ÓÑÃ˵ÄU-AppµÈµÈ£¬ÔÚÕâ½éÉÜÏÂÈçºÎ×Ô½¨ÐÔÄÜ¼à¿Ø¿â
¿ÉÒÔʹÓÃPLCrashReporter»òÕßKSCrash¿â½âÎö±ÀÀ£ÈÕÖ¾²¢·ûºÅ»¯£¬ÔÙÉÏ´«ÖÁºǫ́£¬×Ô¼º×öÊÕ¼¯¼Óͳ¼Æ£¬Ë³´øÌáһϣ¬ÎÒÃÇʹÓÃÁËPLCrashReporter£¬ºó¶ËʹÓÃÁËLaravel£¬ºÜ·½±ãµÄ¿ª·¢ÁËÒ»Ì×¼òµ¥µÄ±ÀÀ£¼°¸÷ÖÖÐÔÄܲÎÊýÊÕ¼¯µÄϵͳ,ËùÒÔÈç¹ûÒª×Ô½¨£¬¿ÉÒÔ¿¼ÂÇÕâ¸ö×éºÏ
CPU¡¢ÄÚ´æ¡¢FPS¼Ç¼¼°±£´æ
1 `CPU`¡¢`FPS`¡¢`MemoryÕ¼ÓÃ`ÍøÉ϶¼ÓÐÏֳɵķ½·¨»ñÈ¡µ½ÕâÈý¸ö²ÎÊý,ÕâÈý¸öÊôÓÚÐÔÄÜ¼à¿Ø£¬¿ÉÒÔ¶¨Ê±¼Ç¼£¬±ÈÈç10S¼Ç¼һ´Îµ½±¾µØÎļþÖУ¬Ã¿´Î´ò¿ªAppÉÏ´«×òÌìµÄÈÕÖ¾¡£Õâ¾ÍÒª×Ô¼ºÖƶ¨ÈÕÖ¾ÉÏ´«µÄ²ßÂÔÁË
¿¨¶ÙÈÕÖ¾ÊÕ¼¯
Óû§ÄܸÐÊܵ½µÄ¿¨¶ÙÒ»°ã¶¼ÊÇÒòΪÔÚÖ÷Ïß³Ì×öÁ˺Äʱ²Ù×÷£¬¾Ù¼¸¸ö»á·¢Éú¿¨¶ÙµÄÀý×Ó£º
1.viewDidLoadÖÐ forÑ»·Öгõʼ»¯10000¸öUILabelʵÀý
2.cellForRow´úÀí·½·¨ÖÐÊÖ¶¯ÐÝÃßusleep(100*1000)
ÈçºÎ¼àÌýÕâЩʼþÄØ£¿²é¿´ÏÂÔ´´úÂë,ºËÐÄ·½·¨CFRunLoopRun¼ò»¯ºóµÄÂß¼ÈçÏ£º
int32_t __CFRunLoopRun()
{
//֪ͨ¼´½«½øÈërunloop
__CFRunLoopDoObservers(KCFRunLoopEntry);
do
{
// ֪ͨ½«Òª´¦ÀítimerºÍsource
__CFRunLoopDoObservers(kCFRunLoopBeforeTimers);
__CFRunLoopDoObservers(kCFRunLoopBeforeSources);
__CFRunLoopDoBlocks(); //´¦Àí·ÇÑÓ³ÙµÄÖ÷Ï̵߳÷ÓÃ
__CFRunLoopDoSource0(); //´¦ÀíUIEventʼþ
//GCD dispatch main queue
CheckIfExistMessagesInMainDispatchQueue();
// ¼´½«½øÈëÐÝÃß
__CFRunLoopDoObservers(kCFRunLoopBeforeWaiting);
// µÈ´ýÄÚºËmach_msgʼþ
mach_port_t wakeUpPort = SleepAndWaitForWakingUpPorts();
// Zzz...
// ´ÓµÈ´ýÖÐÐÑÀ´
__CFRunLoopDoObservers(kCFRunLoopAfterWaiting);
// ´¦ÀíÒòtimerµÄ»½ÐÑ
if (wakeUpPort == timerPort)
__CFRunLoopDoTimers();
// ´¦ÀíÒì²½·½·¨»½ÐÑ,Èçdispatch_async
else if (wakeUpPort == mainDispatchQueuePort)
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()
// UIË¢ÐÂ,¶¯»ÏÔʾ
else
__CFRunLoopDoSource1();
// ÔÙ´ÎÈ·±£ÊÇ·ñÓÐͬ²½µÄ·½·¨ÐèÒªµ÷ÓÃ
__CFRunLoopDoBlocks();
} while (!stop && !timeout);
//֪ͨ¼´½«Í˳örunloop
__CFRunLoopDoObservers(CFRunLoopExit);
} |
ÎÒÃÇ¿ÉÒÔ¿´µ½ÔÚkCFRunLoopBeforeSourcesºÍkCFRunLoopBeforeWaitingµÈ´ýʱ¼ä¹ý³¤¼´¿ÉÅж¨Îª¿¨¶Ù£¬¾ßÌåÔõôËã×÷¿¨¶Ù£¬ÎÒÃǶ¼ÖªµÀFPSΪһÃë60Ö¡×óÓÒ×îºÃ£¬FPS¼´ÎªFrames
Per Second£¬ÑϸñÒâÒåÉÏÒ»Ãë60Ö¡ËãÁ÷³©£¬Ò²¾ÍÊÇÒ»Ö¡ÐèÒª1s/60 = 16.6ms£¬¿¼ÂÇ»áÓÐÆäËûµÄһЩʼþÓ°Ï죬¿ÉÒÔÓÃÁ¬Ðø¼¸´Î50ms»òÕßµ¥´ÎºÄʱ¹ý³¤Åж¨Îª¿¨¶Ù¡£Åж¨Îª¿¨¶ÙÖ®ºó£¬ÎÒÃÇ¿ÉÒÔʹÓÃPLCrashReporter»òÕßKSCrashÉú³ÉÈÕÖ¾¼Ç¼£¬¿ÉÒÔ´æ´¢µ½±¾µØ
ÎÒÃÇ¿ÉÒÔʹÓÃCFRunLoopObserverRefÀ´ÊµÊ±»ñÈ¡NSRunLoop״ֵ̬µÄ±ä»¯,Ò»ÏÂΪһ¸öÑùÀý£º
@interface LagCollectionTool
()
{
int timeoutCount;
CFRunLoopObserverRef observer;
BOOL observeLag;
@public
dispatch_semaphore_t semaphore;
CFRunLoopActivity activity;
}
@end
@implementation LagCollectionTool
+ (instancetype)shareInstance {
static dispatch_once_t onceToken;
static LagCollectionTool *tool = nil;
dispatch_once(&onceToken, ^{
tool = [[LagCollectionTool alloc] init];
});
return tool;
}
- (void)lanuch {
if (observer)
return;
// ÐźÅ
semaphore = dispatch_semaphore_create(0);
// ×¢²áRunLoop״̬¹Û²ì
CFRunLoopObserverContext context = {0,(__bridge
void*)self,NULL,NULL};
observer = CFRunLoopObserverCreate(kCFAllocatorDefault,
kCFRunLoopAllActivities,
YES,
0, &runLoopObserverCallBack, &context);
CFRunLoopAddObserver (CFRunLoopGetMain(), observer,
kCFRunLoopCommonModes);
// ÔÚ×ÓÏß³Ì¼à¿ØÊ±³¤
dispatch_async(dispatch_get_global_queue(0, 0),
^{
while (YES)
{
long st = dispatch_semaphore_wait (semaphore, dispatch_time(DISPATCH_TIME_NOW,
50*NSEC_PER_MSEC));
if (st != 0)
{
if (!observer)
{
timeoutCount = 0;
semaphore = 0;
activity = 0;
return;
}
if (activity==kCFRunLoopBeforeSources || activity==kCFRunLoopAfterWaiting)
{
timeoutCount++;
// NSLog(@"%d", timeoutCount);
if (timeoutCount < 5)
continue;
NSLog(@"----------------¿¨±¬ÁË£¡----------------");
PLCrashReporterConfig *config = [[PLCrashReporterConfig
alloc] initWithSignalHandlerType: PLCrashReporterSignalHandlerTypeBSD
symbolicationStrategy: PLCrashReporterSymbolicationStrategyAll];
PLCrashReporter *crashReporter = [[PLCrashReporter
alloc] initWithConfiguration:config];
NSData *data = [crashReporter generateLiveReport];
PLCrashReport *reporter = [[PLCrashReport alloc]
initWithData:data error:NULL];
NSString *report = [PLCrashReportTextFormatter
stringValueForCrashReport:reporter
withTextFormat:PLCrashReportTextFormatiOS];
//ÉÏ´«¿¨¶ÙÈÕÖ¾Îļþ
}
}
timeoutCount = 0;
}
});
}
static void runLoopObserverCallBack (CFRunLoopObserverRef
observer, CFRunLoopActivity activity, void *info)
{
LagCollectionTool *tool = (__bridge LagCollectionTool
*)info;
tool->activity = activity;
dispatch_semaphore_t semaphore = tool->semaphore;
dispatch_semaphore_signal(semaphore);
} |
´ÓÈݱÀÀ££¬ÉÏ´«±ÀÀ£ÈÕÖ¾
ͨ¹ýʹÓÃNSSetUncaughtExceptionHandler×¢²á×Ô¼ºµÄÒì³£´¦Àí»Øµ÷£¬·¢Éú±ÀÀ£Ê±ÈóÌÐòÏÔʾµÄ´ÓÈÝÒ»µã£¬²»»áÖ±½ÓÉÁÍË£¬¿ÉÒÔµ¯³ö×Ô¼ºµÄ±ÀÀ£Òì³£½çÃæ£¬¿ÉÒԲο¼BilibiliµÄ½çÃæ£¬±ÈÈç˵ǰ·½Óöµ½¸ßÄÜ·´Ó¦Ö®À࣬³ÌÐòÐèÒªÖØÆôÖ®ÀàµÄ£¬²»»áÈÃÓû§¸Ð¾õµ½ºÜͻأµÃÉÁÍËÁË£¬Ò²¿ÉÒÔÔÚÊÕµ½±ÀÀ£ÈÕÖ¾ºóÊÖ¶¯Î¬»¤Runloop£¬ÏÂÃæÊÇÒ»¸öÑùÀý£º
// 1. ×¢²áExceptionHandler
+ (void)installUncaughtExceptionHandler {
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGHUP, SignalHandler);
signal(SIGINT, SignalHandler);
signal(SIGQUIT, SignalHandler);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
}
// 2. ´¦Àí±ÀÀ£ÐÅÏ¢
void SignalHandler(int signal) {
// 1. »ñÈ¡µ÷ÓÃÕ»
// 2. ´¦ÀíÒì³£
// 3. App񜯌
BOOL isContiune = TRUE; // ÊÇ·ñÒª±£»î
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (isContiune) {
for (NSString *mode in (__bridge NSArray *)allModes)
{
CFRunLoopRunInMode((CFStringRef)mode, 0.001, true);
}
}
CFRelease(allModes);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
} |
ÑÓÉ죺
¼à¿ØÏµÍ³²»¹â¾ÖÏÞÓÚÐÔÄÜ¡¢±ÀÀ£ÂÊ£¬Ò²¿ÉÒÔ½«Í³¼Æ²ßÂÔÑÓÉìµ½ÍøÂçÇëÇóÁ¬Í¨ÂÊ»òÕßһЩҵÎñ²ãÃæ£¬¸üºÃµÄ°Ñ¿ØAppµÄÖÊÁ¿
2.3 ÐÔÄܵ÷ÓÅ&AppÌåÑéÓÅ»¯
Ç°ÃæÎÒÃǽéÉÜÁËÈçºÎÓÐЧµØ¼õÉÙ±ÀÀ£¼°ÓÅÑŵش¦Àí±ÀÀ££¬ÏÂÃæÀ´¿´¿´½â¾öÐÔÄÜÎÊÌâÐèҪעÒ⼸µã¡£
2.3.1 ÀÁ¼ÓÔØµÄÀûÓë±×
ÀÁ¼ÓÔØÊÊÓÃÓÚһЩ¿ÉÄܲ»»á¼ÓÔØµÄÒ³Ãæ£¬±ÈÈ絯¿ò¡¢¿ÕÊý¾ÝÒ³ÃæÖ®ÀàµÄ£¬Ê¹Óõõ±¿ÉÒÔ±ÜÃâÄڴ汩ÕÇ£¬Ê¹Óò»ºÃ£¬±ÈÈçÔڱض¨»áµ¯³öµÄÒ³ÃæÖÐʹÓÃÀÁ¼ÓÔØ¿ÉÄÜ»áÔÚÔö¼ÓÒ³ÃæÏìӦʱ¼ä£¬ËùÒÔʹÓÃÀÁ¼ÓÔØÒ»¶¨Òª×¢ÒâʹÓó¡¾°£¬±ÜÃâ²úÉú¸±×÷ÓÃ
2.3.2 ±ÜÃâʹÓÃÖØ»æ
ÖØÐ´ drawRect »òÕß drawReact:inContext·½·¨»áĬÈÏ´´½¨Ò»¸öͼ²ãÉÏÏÂÎÄ£¬Í¼ÐÎÉÏÏÂÎÄËùÐèÒªµÄÄÚ´æÎªÍ¼²ã¿í
* ͼ²ã¸ß * 4×Ö½Ú£¬Í¼²ãÿ´Î½øÐÐÖØ»æÊ±¶¼ÐèҪĨµôÄÚ´æÖØÐ·ÖÅ䣬»á²úÉú¾Þ´óµÄÐÔÄÜ¿ªÏú
UIViewÀàʵ¼ÊÉÏÊǶÔCALayerµÄ·â×°£¬¹ØÓÚUI²ãÃæµÄÐÔÄÜÓÅ»¯ÓкܶණÎ÷£¬¿ÉÒÔ¿´¿´iOS CoreAnimation
ºËÐ͝»¸ß¼¶±à³ÌÖйØÓÚͼ²ãÐÔÄܵÄÒ»ÕÂ
2.3.3 AppÌåÑéÓÅ»¯
̸ÆðAppÌåÑéÓÅ»¯£¬ÆäʵÕâÊǸöÐþѧ£¬ÄãÐèÒªÔÚÐÔÄÜÓëÌåÑéÉÏÕÒµ½Ò»¸öƽºâµã£¬³£¼ûµÄÔã¸âµÄÌåÑé°üÀ¨£º
UITableViewCell ʹÓò»µ±Ôì³É»¬¶¯¿¨¶Ù
´óÁ¿cornerRadiusºÍmaskToBoundsÒ»ÆðʹÓÃÔì³ÉµÄÀëÆÁäÖȾÔì³ÉµÄÐÔÄÜÎÊÌâ
ÍøÂçÇëÇó²Ù×÷ûÓÐÈκÎ״̬չʾ£¬±ÈÈç¼ÓÔØ¿ò¡¢°´Å¥ÖûҵÈ
ÍøÂçÇëÇóûÓнøÐлº´æ
ÕâЩÎÊÌâÖ»ÊÇAppµÄϸ½Ú£¬µ«ÊÇ´Óϸ½ÚÈëÊÖ²ÅÄܸüÏÔµÄרҵ~
ÎÒÃÇÖØµãÌ¸Ì¸ÍøÂçÇëÇóÓÅ»¯£º
2.3.3.1 ÊÖ¶¯Î¬»¤DNS½âÎö
ÓÃwww.manoboo.comÀ´¾ÙÀý,ͨ¹ýÓòÃû·ÃÎÊÊ×ÏÈ»áѰÕÒDNS½âÎö·þÎñÆ÷£¬È»ºó²Å»áÓ³Éäµ½×Ô¼ºµÄ·þÎñÆ÷IPÉÏ¡£ÎÒÃÇÖ±½ÓʹÓÃIPÇëÇó½Ó¿Ú·ÃÎÊÍøÂç×ÊÔ´£¬¿ÉÒÔ±ÜÃâºÜ¶àÎÊÌ⣬µ«ÊÇÓÐÀûÓбף¬ÐèÒª×Ô¼ºÎ¬»¤DNSÓ³É䣬ÔÚÖ±½Ó±ÈÈ磺
ÔËÓªÉÌDNSÁ÷Á¿½Ù³Ö£¬¾ßÌå±íÏÖÔÚÄãµÄH5ÍøÒ³ÄªÃûÆäÃîµÄ±»¼ÓÁË¹ã¸æ(¹ØÓÚÕâ¸öÎÊÌ⣬Ҳ¿ÉÒÔ×öÓòÃû°×Ãûµ¥£¬·Ç±¾ÓòÃû×ÊÔ´½ûÖ¹ÇëÇ󣬻òÕßH5·½Ãæ×ö´¦Àí)£¬Ò²ÓÐ
DNS·þÎñÉÌ(ÈçÍòÍø)½âÎö³öÏÖ¹ÊÕÏÔì³ÉµÄ´óÅúÁ¿Óû§ÎÞ·¨Õý³£Ê¹ÓÃApp£¬°´Ìì¼ÆËã¡£¡£
DNS½âÎöÑÓ³Ù¹ý¸ßÔì³ÉµÄ¼ÓÔØ³¬Ê±µ¼ÖÂÓû§ÌåÑé²î
´ËʱÎÒÃÇ¿ÉÒÔ¿¼ÂÇ×Ô¼ºÊÖ¶¯×öDNS½âÎö,¼òµ¥µã¿ÉÒÔÔÚÍøÂçÇëÇóʱ½«URLÖеÄÓòÃûÌæ»»µô£¬»òÕßÔÚObjective-CÖÐʵÏÖNSURLProtocol(SwiftÖÐΪURLProtocol)µÄ×ÓÀà¶ÔÓ¦µÄ·½·¨£¬×öÈ«¾ÖÌæ»»URL
²»¹ýÒ²ÓÐЩ±×¶Ë£º
ÐèÒªÊÖ¶¯Î¬»¤DNS½âÎö±í£¬½âÎö³ö´íºóÐèÒªÒ»Ì×ÈÝ´í·½°¸£¬±£Ö¤½Ó¿ÚµÄ³©Í¨
HTTPÇëÇó¿ÉÒÔͨ¹ýÉèÖÃheaderÖеÄhost×ֶνøÐÐÍøÂçÇëÇó£¬HTTPSÇëÇó»¹Ðè¶îÍâÅäÖã¬ÊÜÏÞÓÚÆª·ùÔÒò£¬ÏêϸµÄ±×¶ËºÍ½â¾ö·½·¨¿ÉÒÔÔĶÁÏÂÕâÆªÎÄÕÂHTTPDNSÔÚiOSÖеÄʵ¼ù
2.3.3.2 ÍøÂçÇëÇ󻺴æÓÅ»¯
ÊÊÓó¡¾°£ºÒ»Ð©¸üÐÂÆµÂʽϵ͵ij¡¾°£º±ÈÈç¸öÈËÖÐÐÄ
¹ØÓÚÍøÂçÇëÇ󻺴棬App¶ËµÄÍøÂçÇëÇó¶ÔÃæµ½ºó¶Ë¸ü¶àµÄÊÇÔöɾ¸Ä²é£¬Õâ¸ö·½ÃæÐèÒªºÍºó¶ËÅäºÏ£¬ÊÇ·ñ×ÊÔ´¸Ä±ä¼´ºó¶ËÊÇ·ñÐèÒªÖØÐ¼ìË÷»òÐÞ¸ÄÊý¾Ý£¬Õâ¸öʱºòÎÒÃǾÍÐèÒªÒ»¸övalue±ÈÈçʱ¼ä´ÁLast-Modified»òÕß±êʶETagÀ´¸æÖª·þÎñÆ÷×Ô¼ºµ±Ç°µÄ×ÊÔ´±ê¼Ç£¬Ä¿Ç°³£ÓõIJßÂÔΪ£º
ÒÔʱ¼ä´ÁLast-ModifiedΪÀý
App¶ËµÚÒ»´ÎÇëÇó½Ó¿Ú£¬·þÎñ¶Ë·µ»Ø³É¹¦£¬HTTP StatusΪ200£¬²¢ÇÒÔÚ·µ»ØµÄHeaderÖÐÓÃLast-Modified±íÃ÷·þÎñÆ÷ÖиÃ×ÊÔ´×îºó±»Ð޸ĵÄʱ¼ä
App¶ËµÚ¶þ´ÎÇëÇó¸Ã½Ó¿Ú£¬HeaderÖд«µÝ±¾µØ»º´æµÄHeaderÖеÄLast-Modified,Èç¹û·þÎñÆ÷¶ËµÄ×ÊÔ´²¢Î´·¢Éú±ä»¯£¬Ôò»á·µ»ØHTTP
StatusΪ304£¬ÎÒÃÇÖ±½Ó¿ÉÒÔʹÓñ¾µØµÄ»º´æ£¬´«ÊäÁ÷Á¿¸üÉÙ£¬Ïà¶Ô¶øÑÔ£¬Óû§µÄµÈ´ýʱ¼ä»á¸ü¶Ì
×¢£º
Á¿»¯¶ø·Ç²Â²â£¬ÕâÊÇÎÒÃÇ¿ª·¢¹ý³ÌÖеÄÒ»¸öÔÔò£¬µ±Óöµ½ÐÔÄÜÎÊÌâʱ£¬ÎÒÃÇ¿ÉÒÔʹÓÃinstrumentsÀ´²âÁ¿Êµ¼ÊÔËÐйý³ÌÖеĸ÷¸ö²ÎÊý£¬ÕÒµ½ÎÊÌâËùÔÚ£¨½¨ÒéÕæ»úµ÷ÊÔ¶ø²»ÊÇÄ£ÄâÆ÷£¬Õæ»ú²ÅÄܸü¸ßµÄ»¹ÔÐÔÄÜÎÊÌ⣩


instruments¹¤¾ß³£¼û¹¦ÄÜ
µã»÷ÓÒÉÏ·½¼ÓºÅ»¹Óиü¶à¹¤¾ß+
instrumentsÖй¤¾ß¶¼Óи÷×ÔµÄÓô¦£¬±ÈÈç¿ÉÒÔʹÓÃLeask²é¿´AppÔËÐйý³ÌÖеÄÄÚ´æÐ¹Â¶£¬Ê¹ÓÃTimeProfiler²é¿´AppÆô¶¯ºÄʱ»òÕß·½·¨ºÄʱ,»òÕß͵ÀÁÒ»µã¿ÉÒÔʹÓÃCACurrentMediaTime()Á½´ÎµÄ²îÖµ¼ÆËã·½·¨ºÄʱ
½áÓï
ÊÜÏÞÓÚÆª·ùÔÒò£¬ÓÐЩµãÒ²ÊÇÒ»¸Å¶ø¹ý£¬iOSÖÐÈçºÎÓÅ»¯Ò»¸öÏîÄ¿£¬ÕâÊÇÒ»ÃźÜÉîµÄѧÎÊ£¬ÖªÊ¶µã·¶Î§ºÜ¹ã£¬ÎÒÒ²Ö»ÊÇÉæ¼°µ½ÁËÒ»²¿·Ö£¬Ñ§ÎÞÖ¹¾³ÂÍê³É¹¤×÷µÄͬʱÎÒÃÇÒ²¿ÉÒÔ×öÒ»¸ö¿á¿áµÄ³ÌÐòÔ±£¬Ñ§Ñ§HaskellÈ¥ÌåÑéϺ¯Êýʽ±à³Ì˼άµÄÀÖȤ£¬»òÕ߸ã¸ãLLDB¸üºÃµÃ×ö¸öDebugger
|