×î½ü±»°²ÅÅfixÏîÄ¿µÄËæ»úcrashÎÊÌâ,
´ó´óССÐÞ¸´Á˲¶à10¸öissue, ×ܽáһϷ¢ÏÖÕâЩÎÊÌâ»ò¶à»òÉÙ¶¼ÊÇÓÉ´úÂëϰ¹ßºÍ±à³Ì¹æ·¶ÒýÆðµÄ, ¿É¼ûÒ»¸öºÃµÄ±àÂëϰ¹ßÊǶàôµÄÖØÒª!
³Ã×ÅÕâÁ½ÌìÐݼٽ«×Ô¼ºËùÈÏΪµÄһЩ±È½ÏºÃµÄ´úÂë¹æ·¶ÕûÀíÒ»ÏÂ, ²¢½áºÏ֮ǰÓöµ½µÄʵ¼Êcase¸ú´ó¼Ò·ÖÏíÒ»ÏÂ.
ÃüÃû¹æ·¶
×ܵÄÀ´Ëµ, iOSÃüÃûÁ½´óÔÔòÊÇ:¿É¶ÁÐԸߺͷÀÖ¹ÃüÃû³åÍ»(ͨ¹ý¼Óǰ׺À´±£Ö¤). Objective-C
µÄÃüÃûͨ³£¶¼±È½Ï³¤, Ãû³Æ×ñÑÍÕ·åʽÃüÃû·¨. Ò»¸öºÃµÄÃüÃû±ê×¼ºÜ¼òµ¥, ¾ÍÊÇ×öµ½ÔÚ¿ª·¢ÕßÒ»¿´µ½Ãû×Öʱ,
¾ÍÄܹ»¶®µÃËüµÄº¬ÒåºÍʹÓ÷½·¨. ÁíÍâ, ÿ¸öÄ£¿é¶¼Òª¼ÓÉÏ×Ô¼ºµÄǰ׺, ǰ׺ÔÚ±à³Ì½Ó¿ÚÖзdz£ÖØÒª, ¿ÉÒÔÇø·ÖÈí¼þµÄ¹¦ÄÜ·¶³ë²¢·ÀÖ¹²»Í¬Îļþ»òÕßÀàÖ®¼äÃüÃû·¢Éú³åÍ»,
±ÈÈçÏà²áÄ£¿é(PhotoGallery)µÄ´úÂë¶¼ÒÔPG×÷Ϊǰ׺: PGAlbumViewController,
PGDataManager.
1). ³£Á¿µÄÃüÃû
¶ÔÓÚ³£Á¿µÄÃüÃû×îºÃÔÚÇ°Ãæ¼ÓÉÏ×Öĸk×÷Ϊ±ê¼Ç. Èç:
static const NSTimeInterval kAnimationDuration = 0.3; |
¶¨Òå×÷ΪNSDictionary»òÕßNotificationµÈµÄKeyÖµ×Ö·û´®Ê±¼ÓÉÏconst¹Ø¼ü×Ö,
ÒÔ·ÀÖ¹±»ÐÞ¸Ä. Èç:
NSString *const UIApplicationDidEnterBackgroundNotification |
Tips:
I. Èô³£Á¿×÷ÓÃÓò³¬³ö±àÒëµ¥Ôª(ʵÏÖÎļþ), ÐèÒªÔÚÀàÍâ¿É¼ûʱ, ʹÓÃextern¹Ø¼ü×Ö, ²¢¼ÓÉϸÃÀàÃû×÷Ϊǰ׺.
Èç extern NSString *const PGThumbnailSize
II.È«¾Ö³£Á¿(֪ͨ»òÕ߹ؼü×ÖµÈ)¾¡Á¿ÓÃconstÀ´¶¨Òå. ÒòΪÈç¹ûʹÓú궨Òå, Ò»À´ºê¿ÉÄܱ»Öض¨Òå.
¶þÀ´ÒýÓò»Í¬µÄÎļþ¿ÉÄܻᵼÖºêµÄ²»Í¬. P.S. ¶ÔÓÚ££defineÒ²Ìí¼ÓÒ»ÏÂǰ׺k(Ç¿ÆÈÖ¢, ¹þ¹þ...)
2). ö¾ÙµÄÃüÃû
¶ÔÓÚö¾ÙÀàÐÍ, ¾³£»á¿´µ½Ö®Ç°µÄCµÄ¶¨Ò巽ʽ:
typedef enum : { CameraModeFront, CameraModeLeft, CameraModeRight, } CameraMode; |
²»ÖªµÀÊÇÖ×ôÁË, ÿ´Î¿´µ½ÕâÖÖ¶¨Ò巽ʽ×ÜÊǸоõ¹Ö¹ÖµÄ, ×÷Ϊһ¸öÕý×ÚµÄiOS¿ª·¢Õßµ±È»ÒªÒÔObjective-CµÄ·½Ê½À´¶¨ÒåÀ²,
¹þ¹þ... ÄÇObjective-CÊÇÔõô¶¨ÒåµÄÄØ? ºÜ¼òµ¥, µ½SDKÀïÃæ¿´¿´AppleÊÇÔõô×öµÎ:
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) { UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, }; |
Õâ±ßÐèҪעÒâµÄÊÇ: ö¾ÙÀàÐÍÃüÃûÒª¼ÓÏà¹ØÀàÃûǰ׺²¢ÇÒö¾ÙÖµÃüÃûÒª¼Óö¾ÙÀàÐÍǰ׺.
3). ±äÁ¿ºÍ¶ÔÏóµÄÃüÃû
¸øÒ»¸ö¶ÔÏóÃüÃûʱ½¨Òé²ÉÓÃÐÞÊÎ+ÀàÐ͵ķ½Ê½. Èç¹ûÖ»ÓÃÐÞÊÎÃüÃû»áÒýÆðÆçÒå, ±ÈÈçtitle (Õâ¸öµ½µ×ÊǸöNSString»¹ÊÇUILabel?).
ͬÑùµÄ, Èç¹ûÖ»ÓÃÀàÐÍÀ´ÃüÃûÔò»áȱʧ×÷ÓÃÐÅÏ¢, ±ÈÈçlabel (ºÃ°É, ÎÒÖªµÀÄãÊǸöUILabel,
µ«ÊÇÎÒ²»ÖªµÀËüÊÇÓÃÀ´×öʲôµÄѽ?). So, ÕýÈ·µÄÃüÃû·½Ê½Îª:
titleLabel //±íʾ±êÌâµÄlabel, ÊÇUILabelÀàÐÍ confirmButton //±íʾȷÈϵÄbutton, ÊÇUIButtonÀàÐÍ |
¶ÔÓÚBOOLÀàÐÍ, Ó¦¼ÓÉÏisǰ׺, ±ÈÈç- (BOOL)isEqualToString:(NSString
*)aStringÕâÑù»á¸ü¼ÓÇåÎú. Èç¹ûij·½·¨·µ»Ø·ÇÊôÐ﵀ BOOL Öµ, ÄÇôӦ¸ù¾ÝÆä¹¦ÄÜ, Ñ¡Óà has
»ò is µ±Ç°×º, Èç- (BOOL)hasPrefix:(NSString *)aString
Tip: Èç¹ûij¸öÃüÃûÒѾºÜÃ÷È·ÁË, ΪÁ˼ò½à¿ÉÒÔʡȥÀàÐÍÃû. ±ÈÈçscores, ºÜÃ÷ÏÔÊǸöarrayÁË,
¾Í²»±ØÃüÃû³ÉscoreArrayÁË
±àÂë¹æ·¶
±àÂë¹æ·¶¼òµ¥À´Ëµ¾ÍÊÇΪÁ˱£Ö¤Ð´³öÀ´µÄ´úÂë¾ß±¸Èý¸öÔÔò:¿É¸´ÓÃ, Ò×ά»¤, ¿ÉÀ©Õ¹. ÕâÆäʵҲÊÇÃæÏò¶ÔÏóµÄ»ù±¾ÔÔò.
¿É¸´ÓÃ, ¼òµ¥À´Ëµ¾ÍÊDz»ÒªÐ´Öظ´µÄ´úÂë, ÓÐÖØ¸´µÄ²¿·ÖÒª¾¡Á¿·â×°ÆðÀ´ÖØÓÃ. ·ñÔòÐÞ¸ÄÎļþµÄʱºòµÃÂúµØÕÒÏàͬÂß¼µÄµØ·½...Õâ¸ö¾ÍÓÃno
zuo no dieÀ´ÃèÊö°É, ¹þ¹þ...Ò×ά»¤, ¾ÍÊDz»Òª°Ñ´úÂ븴ÔÓ»¯, ²»ÒªÈ¥Ð´¾Þ¸´ÔÓÂß¼µÄ´úÂë,
¶øÊǰѸ´ÔÓµÄÂß¼´úÂë²ð·Ö¿ªÒ»¸ö¸öСµÄÄ£¿é, ÕâÒ²ÊÇDo one thingµÄ¸ÅÄî, ÿ¸öÄ£¿é(»òÕߺ¯Êý)Ö°ÔðÒªµ¥Ò»,
ÕâÑùµÄ´úÂë»áÒ×ÓÚά»¤, Ò²²»ÈÝÒ׳ö´í. ¿ÉÀ©Õ¹ÔòÊÇÒªÇóд´úÂëʱҪ¿¼ÂǺóÃæµÄÀ©Õ¹ÐèÇó, Õâ¸öÊôÓڼܹ¹²ãÃæµÄ¶«¶«,
ÀûÓöÔÓ¦µÄÉè¼ÆÄ£Ê½À´±£Ö¤, ºóÃæÓлú»áµ¥¶ÀдÎÄ̽ÌÖ¡£
±àÂë¹æ·¶Ö±½Óͨ¹ýʾÀýÀ´½éÉÜ, ±Ï¾¹¶ÔÓÚ³ÌÐòÔ±À´ËµÒ»¸öDemoʤ¹ýǧÐÐÎÄ×Ö(ÓÐͬ¸ÐµÄС»ï°éÈÃÎÒ¿´µ½ÄãÃǵÄË«ÊÖ,
¹þ¹þO(¡É_¡É)O~~). ÏÂÃæµÄ²¿·ÖʾÀýÑ¡×Ôrichieyang²©ÎÄ, дµÄºÜºÃµÄһƪÎÄÕÂ, ÍÆ¼ö´ó¼Ò¿´Ò»ÏÂ,
ÎÒ×Ô¼ºÒ²ÊÇÊÜÒæ·Ëdz.
1). ÅжÏnil»òÕßYES/NO
Preferred:
if (someObject) { ... } if (!someObject) { ... } |
Not preferred:
if (someObject == YES) { ...} if (someObject != nil) { ...} |
if (someObject == YES)ÈÝÒ×Îóд³É¸³ÖµÓï¾ä, ×Ô¼º¸ø×Ô¼ºÍÚ¿ÓÁË...¶øÇÒif (someObject)д·¨ºÜ¼ò½à,
ºÎÀÖ¶ø²»ÎªÄØ?
2). Ìõ¼þ¸³Öµ
Preferred:
result = object ? : [self createObject]; |
Not preferred:
result = object ? object : [self createObject]; |
Èç¹ûÊÇ´æÔھ͸³Öµ±¾Éí, ÄǾͿÉÒÔÕâÑù¼òд, ¶à¼ò½à°¡, ¹þ¹þ...
3). ³õʼ»¯·½·¨
Preferred:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve"]; NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal"}; NSNumber *shouldUseLiterals = @YES; NSNumber *buildingZIPCode = @10018; |
µÚÒ»¸öºÃ´¦»¹ÊǼò½à, µÚ¶þ¸öºÃ´¦ÊÇ¿ÉÒÔ·ÀÖ¹³õʼ»¯½øÈ¥nilÖµÔì³Écrash
4). ¶¨ÒåÊôÐÔ
Preferred:
@property (nonatomic, readwrite, copy) NSString *name; |
½¨Ò鶨ÒåÊôÐÔµÄʱºò°ÑËùÓеIJÎÊýдȫ, ÓÈÆäÊÇÈç¹ûÏ붨Òå³ÉÖ»¶ÁµÄ(·ÀÖ¹ÍâÃæÐÞ¸Ä)ÄÇÒ»¶¨Òª¼ÓÉÏreadonly,
ÕâÒ²ÊÇ´úÂ밲ȫÐÔµÄÒ»¸öϰ¹ß.
Èç¹ûÊÇÄÚ²¿Ê¹ÓõÄÊôÐÔ, ÄÇô¾Í¶¨Òå³É˽ÓеÄÊôÐÔ(¶¨Òåµ½.mµÄclass extensionÀïÃæ)
¶ÔÓÚÓµÓÐMutable×ÓÀàÐ͵ĶÔÏó(e.g. NSString, NSArray, NSDictionary)Ò»¶¨Òª¶¨Òå³ÉcopyÊôÐÔ.
Why? ʾÀý: NSArrayµÄarray = NSMutableArrayµÄmArray; Èç¹ûmArrayÔÚij¸öµØ·½¸Ä±äÁË,
ÄÇarrayÒ²»á¸úןıä. So, make sense?
¾¡Á¿²»Òª±©Â¶mutableÀàÐ͵ĶÔÏóÔÚpublic interface, ½¨ÒéÔÚ.h¶¨ÒåÒ»¸öInmutableÀàÐ͵ÄÊôÐÔ,
È»ºóÔÚ.mµÄgetº¯ÊýÀïÃæ·µ»ØÒ»¸öÄÚ²¿¶¨ÒåµÄmutable±äÁ¿. Why? For security as
well!
5). BOOL¸³Öµ
Preferred:
Not preferred:
BOOL isAdult; if (age > 18) { isAdult = YES; } else { isAdult = NO; } |
ΪʲôҪÕâÃ´Ð´ÄØ, ÎÒ²»¸æËßÄã, ¹þ¹þ¹þ...
6) ¾Ü¾øËÀÖµ
Preferred:
if (car == Car.Nissan) or const int adultAge = 18; if (age > adultAge) { ... } |
Not preferred:
if (carName == "Nissan") or if (age > 18) { ... } |
ËÀֵÿ´ÎÐ޸ĵÄʱºòÈÝÒ×±»ÒÅÍü, µØ·½¶àÁËÕÒÆðÀ´¾Í±¯¾çÁË. ¶øÇÒ¶¨Òå³Éö¾Ù»òÕßstatic¿ÉÒÔÈôíÎó·¢ÉúÔÚ±àÒë½×¶Î.
ÁíÍâ½ö½ö¿´µ½Ò»¸öÊý×Ö, ÍêÈ«²»ÖªµÀÕâ¸öÊý×Ö´ú±íµÄÒâÒå. ÄÉÄá?
7). ¸´ÔÓµÄÌõ¼þÅжÏ
Preferred:
if ([self canDeleteJob:job]) { ... } - (BOOL)canDeleteJob:(Job *)job { BOOL invalidJobState = job.JobState == JobState.New || job.JobState == JobState.Submitted || job.JobState == JobState.Expired; BOOL invalidJob = job.JobTitle && job.JobTitle.length; return invalidJobState || invalidJob; } |
Not preferred:
if (job.JobState == JobState.New || job.JobState == JobState.Submitted || job.JobState == JobState.Expired || (job.JobTitle && job.JobTitle.length)) { //.... } |
ÇåÎúÃ÷ÁË, ÿ¸öº¯ÊýDO ONE THING!
8). ǶÌ×ÅжÏ
Preferred:
if (!user.UserName) return NO; if (!user.Password) return NO; if (!user.Email) return NO; return YES; |
Not preferred:
BOOL isValid = NO; if (user.UserName) { if (user.Password) { if (user.Email) isValid = YES; } } return isValid; |
Ò»µ©·¢ÏÖij¸öÌõ¼þ²»·ûºÏ, Á¢¼´·µ»Ø, ÌõÀí¸üÇåÎú
9). ²ÎÊý¹ý¶à
Preferred:
- (void)registerUser(User *user) { // to do... } |
Not preferred:
- (void)registerUserName:(NSString *)userName password:(NSString *)password email:(NSString *)email { // to do... } |
µ±·¢ÏÖʵÏÖijһ¹¦ÄÜÐèÒª´«µÝµÄ²ÎÊýÌ«¶àʱ, ¾ÍԤʾ×ÅÄãÓ¦¸Ã¾ÛºÏ³ÉÒ»¸ömodelÀàÁË...ÕâÑù´úÂë¸üÕû½à,
Ò²²»ÈÝÒ×ÒòΪ²ÎÊýÌ«¶àµ¼Ö³ö´í¡£
10). »Øµ÷·½·¨
Preferred:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; |
º¯Êýµ÷ÓõĿÉÖªÐÔ, »Øµ÷ʱ±»µ÷ÓÃÕßÒªÖªµÀÆäµ÷ÓÃÕß, ·½±ãÐÅÏ¢µÄ´«µÝ, ËùÒÔ½¨ÒéÔڻص÷·½·¨ÖеÚÒ»¸ö²ÎÊýÖмÓÉϵ÷ÓÃÕß¡£
Well, ²»Öª²»¾õÒѾÕûÀíÁË10¸öÁË, ¶î, Ì«¶àÁË, ²»ÖªµÀͯЬÃÇ»¹ÓÐľÓÐÄÍÐÄ¿´ÁË, ºÃ°É, ÕâÒ»¶Î¾Íµ½´ËΪֹ°É,
ÏÂÃæÐ´Ò»ÏÂblockµÄ±àÂë¹æ·¶, ¸÷λ¿´¹Ù, Ô¤ÖªºóÊÂÈçºÎ, ÇÒ¼ÌÐølook look, ¹þ¹þ...
BlockµÄÑ»·ÒýÓÃÎÊÌâ
BlockȷʵÊǸöºÃ¶«Î÷, µ«ÊÇÓÃÆðÀ´Ò»¶¨Òª×¢ÒâÑ»·ÒýÓõÄÎÊÌâ, ·ñÔòÒ»²»Ð¡ÐÄÄã¾Í»á·¢ÏÖ, Oh My
God, ÎÒµÄdeallocÖ׾²»×ßÁË...
__weak typeof(self) weakSelf = self; dispatch_block_t block = ^{ [weakSelf doSomething]; // weakSelf != nil // preemption, weakSelf turned nil [weakSelf doSomethingElse]; // weakSelf == nil }; |
Èç´ËÔÚÉÏÃæ¶¨ÒåÒ»¸öweakSelf, È»ºóÔÚblockÌåÀïÃæÊ¹ÓøÃweakSelf¾Í¿ÉÒÔ±ÜÃâÑ»·ÒýÓõÄÎÊÌâ.
ÄÇôÎÊÌâÀ´ÁË...ÊDz»ÊÇÕâÑù¾ÍÍêȫľÓÐÎÊÌâÁË? ºÜ²»ÐÒ, ´ð°¸ÊÇNO, »¹ÊÇÓÐÎÊÌâ¡£ÎÊÌâÊÇblockÌåÀïÃæµÄselfÊÇweakµÄ,
ËùÒÔ¾ÍÓпÉÄÜÔÚijһ¸öʱ¶ÎselfÒѾ±»ÊÍ·ÅÁË, ÕâʱblockÌåÀïÃæÔÙʹÓÃselfÄǾÍÊÇnil, È»ºó...È»ºó¾Í±¯¾çÁË...ÄÇôÖ×ô°ìÄØ?
__weak typeof(self) weakSelf = self; myObj.myBlock = ^{ __strong typeof(self) strongSelf = weakSelf; if (strongSelf) { [strongSelf doSomething]; // strongSelf != nil // preemption, strongSelf still not nil [strongSelf doSomethingElse]; // strongSelf != nil } else { // Probably nothing... return; } }; |
½â¾ö·½·¨ºÜ¼òµ¥, ¾ÍÊÇÔÚblockÌåÄÚdefineÒ»¸östrongµÄself, È»ºóÖ´ÐеÄʱºòÅжÏÏÂselfÊÇ·ñ»¹ÔÚ,
Èç¹ûÔھͼÌÐøÖ´ÐÐÏÂÃæµÄ²Ù×÷, ·ñÔòreturn»òÅ׳öÒì³£.
ʲôÇé¿öÏ»á³öÏÖblockÀïÃæselfÑ»·ÒýÓõÄÎÊÌâ? Õâ¸öÎÊÌâÎʵĺÃ, ¹þ¹þ...¼òµ¥À´Ëµ¾ÍÊÇË«±ßÒýÓÃ,
Èç¹ûblockÊÇselfÀàµÄproperty (´ËʱselfÒѾretainÁËblock), È»ºóÔÚblockÄÚÓÖÒýÓÃÁËself,
Õâ¸öÇé¿öϾͿ϶¨»áÑ»·ÒýÓÃÁË...
P.S. RACÀïÃæÓж¨ÒåºÃµÄ@weakify(self)ºÍ@strongify(self), ÓÃÆðÀ´»Ò³£»Ò³£µÄ·½±ã,
Ȱ¾ý³¢ÊÔÒ»ÏÂ^_^
ÄÇЩÄêÓöµ½µÄCrash
¶àÏß³Ìͬ²½ÎÊÌâÔì³ÉµÄCrash
Õâ¸öÆäʵ»¹Âù³£¼ûµÄ, ÓÈÆäÊÇÔÚ¶àÏ̷߳ºÀÄʹÓõĽñÌì...Äã¿ÉÒÔʹÓöàÏß³Ì, µ«ÄãÒªÖªµÀ±£»¤Ëüѽ, ¹þ¹þ.
¶ÔÓÚÊý¾ÝÔ´»òmodelÀàÒ»¶¨Òª×¢Òâ¶àÏß³Ìͬʱ·ÃÎʵÄÇé¿ö, ÎÒ¸öÈ˱ȽÏϲ»¶ÓÃGCDµÄ´®ÐжÓÁÐÀ´Í¬²½Ïß³Ì.
ObserverµÄÒÆ³ý
ÏÖÔڵĴúÂëÀïÃæºÜ¶àÐèÒªÓõ½Observer, ¸ù¾Ý±»¹Û²ì¶ÔÏóµÄ״̬À´ÏàÓ¦µÄUpdate UI»òÕßÖ´ÐÐij¸ö²Ù×÷.
×¢²áobserverºÜ¼òµ¥, µ«ÊÇÒÆ³ýµÄʱºò¾Í³öÎÊÌâÁË, ҪôÊÇÍü¼ÇÒÆ³ýobserverÁË, ҪôÊÇÒÆ³ýµÄʱ»ú²»¶Ô.
Èç¹ûij¸ö±»¹Û²ì¶ÔÏóÒѾ±»ÊÍ·ÅÁË, observer»¹ÔÚ, Äǽá¹ûÖ»ÄÜÊÇcrashÁË, ËùÒÔÇмÇÖÁÉÙÔÚdeallocÀïÃæÒÆ³ýÒ»ÏÂobserver...
NSArray, NSDictionary³ÉÔ±µÄÅпձ£»¤
ÔÚaddObject»òinsertObjectµ½NSArray»òÕßNSDictionaryʱ×îºÃ¼ÓÒ»ÏÂÅпձ£»¤,
ÓÈÆäÊÇÍøÂçÏà¹ØµÄÂß¼, Èç¹ûÍøÂç·µ»ØÎª¿Õ(jason½âÎö³öÀ´Îª¿Õ), µ«Ä㻹ÊÇÒãÈ»¾öÈ»µÄaddµ½arrayÀïÃæ,
ÄÇô...
×îºóÒ»µã¾ÍÊÇcommit´úÂë֮ǰһ¶¨Òª±£Ö¤Ä¾ÓÐwarning, ľÓÐÄÚ´æÐ¹Â¶, È·±£¶¼OKÖ®ºóÔÙÉÏ´«´úÂë.
ÆäʵºÜ¼òµ¥, ÉÏ´«´úÂë֮ǰCommand + Shift + B¾²Ì¬·ÖÎöÒ»ÏÂ, ¿´¿´ÓÐľÓÐʲôissue...¾ÍÏÈдÕâô¶à°É,
ÒÔºóÓöµ½¸ü¶àµÄ¿Óºó, ÎÒÒ»¶¨»áÅÀ³öÀ´ÔÙ¹ýÀ´²¹³äµÄ, to be continued...
|