Objective-C və Kakao yazarkən istifadə etdiyiniz ən yaxşı təcrübələr hansılardır?

Mən HIG (çox rahatdır!) Haqqında bilirəm, Amma Objective-C yazarkən və daha çox Kakao (ya da KakaoTouch) istifadə edərkən hansı proqramlaşdırma üsullarını istifadə edirsiniz?

348
01 окт. pixel 01 oct təşkil edir. 2008-10-01 05:13 '08 at 5:13 pm 2008-10-01 05:13
@ 33 cavab
  • 1
  • 2

Başladığım bir neçə şey var, bunları standart hesab etmirəm:

1) Əmlakın inkişafı ilə artıq "şəxsi" prefiks üçün "_" sinif dəyişənlərini istifadə etmirəm. Hər hansı bir dəyişən digər siniflər üçün əlçatan olarsa, bunun üçün bir əmlak olmamalıdırmı? Kodun daha çirkin olması üçün həmişə "_" prefiksini sevməmişəm və indi onu tərk edə bilərəm.

2) Şəxsi əşyalar haqqında danışarkən, məsələn, bir sinif genişlənməsində .m faylında xüsusi üsul tanımlamalarını yerləşdirməyi üstün edirəm, məsələn:

 #import "MyClass.h" @interface MyClass () - (void) someMethod; - (void) someOtherMethod; @end @implementation MyClass 

Nə üçün .h faylını xaricdəki əşyalarla maraqlandırmır? Boş (), .m faylında xüsusi kateqoriyalar üçün işləyir və bildirilən üsulları tətbiq etmədiyiniz təqdirdə tərtib xəbərdarlıqları verir.

3) .m faylının başlanğıcında, @synthesize direktivlərinin altındakı dealloc qoydu. Sinifdə düşünmək istədiyiniz şeylər siyahısının başında olmalısan? Bu xüsusilə bir iPhone kimi bir mühitdə doğru.

3.5) Cədvəl hüceyrələrində hər element (qutunun özü daxil olmaqla) performans üçün qeyri-şəffaf olun. Bu, müvafiq fon fonunu bütünlükdə yerləşdirmək deməkdir.

3.6) NSURLConnection istifadə edərkən, bir qayda olaraq, nümayəndə üsulunu tətbiq edə bilərsiniz:

 - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { return nil; } 

Çox veb çağırışları çox təkdir və bu xüsusilə veb xidmətləri çağırışları üçün önbellekli cavablar almaq istədiyiniz qaydan çox istisna deyil. Göstərilən metodu həyata keçirərkən cavabların önbelleğini kəsər.

Həm də maraqlı olan iPhone Matrix (iPhone poçt siyahısında əldə edilmiş) olan faydalı iPhone məsləhətləri. Daha çox var, amma onlar ən faydalı idilər, düşündüm (bir neçə bit indi orijinaldan cümlələri əlavə etmək üçün bir qədər düzəldilmişdir):

4) Lazım olduqda, məsələn, CoreLocation ilə işləyərkən yalnız ikiqat dəqiqliyi istifadə edin. Gücünüzü float olaraq saxlayacaq şəkildə 'f' dəki sabitləri tamamladığınızdan əmin olun.

 float val = someFloat * 2.2f; 

someFloat , həqiqətən, ikiqat ola biləcəyiniz zaman əsasən əhəmiyyətlidir, qarışıq rejimdə someFloat ehtiyac yoxdur, çünki depoda "val" da dəqiqliyi someFloat . Üzən nöqtə nömrələri iPhone donanmasında dəstəklənir, baxmayaraq ki, bir həssas arifmetik əleyhinə olaraq cüt həssas arifmetikləri yerinə yetirmək daha uzun sürə bilər. Referanslar:

Köhnə telefonlarda ehtimal ki, hesablamalar eyni sürətdə işləyir, ancaq qeydiyyatdan daha çox vahid həssas komponentlərə malikdirlər, belə ki, bir çox hesablamalar üçün vahid dəqiqlik daha sürətli olacaqdır.

5) Xassələrini nonatomic olaraq təyin edin. Default olaraq, onlar atomic və sintez zamanı çoxbucaqlı problemlərin qarşısını almaq üçün semafor kodu yaranır. 99% -nin ehtimal ki, bu barədə narahat olmayın və kod çox şeyə şişirilir və qeyri-təbii olaraq təyin edildikdə yaddaş baxımından daha səmərəlidir.

6) SQLite, böyük məlumat dəstini önbelleğe almanın çox, çox sürətli bir yolu ola bilər. Məsələn, bir xəritə tətbiqi SQLite fayllarında parçaları önbelleğe ala bilər. Ən bahalı hissəsi disk I / O'dır. BEGIN; göndərərək bir çox kiçik qeydlər çəkinin BEGIN;COMMIT; böyük bloklar arasında. Məsələn, hər yeni təqdimata sıfırlanan 2 saniyəli bir taymer istifadə edirik. Bu müddətdən sonra, bütün qeydlərinizin bir böyük parçaya keçməsinə gətirib çıxaran COMMIT göndəririk. SQLite, əməliyyat məlumatlarını diskə daşıyır və bütün əməliyyatları bir faylya qruplaşdıraraq bir çox əməliyyat faylını yaratmaqdan çəkinmək üçün bu Başlanğıc / Bitirmə əməliyyatını edir.

Bundan əlavə, SQL əsas işdə olduğu təqdirdə GUI-nı blok edəcək. Çox uzun sorğunuz varsa, sorğularınızı statik obyektlər kimi saxlamaq və ayrı bir iş parçacığında SQL-i tövsiyə etmək məsləhətdir. @synchronize() {} bloklarında verilənlər bazasını dəyişən hər şeyi @synchronize() {} əmin olun. Qısa sorgular üçün, rahatlıq üçün əsas mövzuda yalnız şeyləri buraxın.

Sənəd köhnəlmiş görünsə də, burada SQLite'yi optimallaşdırmaq üçün əlavə məsləhətlər verilir. Onların bir çoxu yəqin ki, yaxşıdır;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

400
01 окт. Kendall Helmstetter Gelner tərəfindən verilmiş cavab 01 oktyabr 2008-10-01 06:17 '08 at 6:17 2008-10-01 06:17

Bilinməyən dizgiləri format stringləri kimi istifadə etməyin.

Metodlar və ya funksiyalar bir format dizgesinin bir argümanı aldıqda, format stringinin məzmununa nəzarət etdiyinizdən əmin olmalısınız.

Məsələn, strings yazarkən, NSLog dakı tək arqument kimi bir string dəyişənini keçmək cazibədardır:

border=0
  NSString *aString = // get a string from somewhere; NSLog(aString); 

Problem simli format simvolu olaraq şərh olunan simvol ola bilər. Bu səhv nəticələrə, uğursuzluqlara və təhlükəsizlik problemlərinə səbəb ola bilər. Bunun əvəzində, format stringində bir string dəyişənini əvəz etməliyəm:

  NSLog(@"%@", aString); 
110
06 окт. Cavab verildi 2008-10-06 19:46 '08 saat 07:46 'de 2008-10-06 19:46

Müxtəlif mühitdə istifadə etdiyinizdən çox standart Kakao adlandırma və formatlaşdırma konvensiyaları və terminologiyasından istifadə edin. Orada bir çox Kakao geliştiricisi var və onlardan biri kodunuzla işə başlayanda, başqa bir Kakao kodu görünsün və görünsəydi, bu daha əlçatan olacaq.

Nə etməli və nə etməməli olduğuna dair nümunələr:

  • id m_something; obyektin interfeysində və bir üzv dəyişən və ya sahə adlanır; _something üçün something və ya something istifadə edin və bir nümunə dəyişən adını verin.
  • -getSomething ; Doğru kakao adı yalnız bir -something .
  • Setter -something: bu olmalıdır -setSomething:
  • Metodun adı argümanlarla birləşir və kolonları ehtiva edir; bu -[NSObject performSelector:withObject:] deyil, NSObject::performSelector .
  • Metod adları, parametrləri, dəyişənləri, sinif adları və s. İçərisində interaktiv qovluqlardan (CamelCase) istifadə edin və aşağı xəttlərdə deyil (alt çərçivələr).
  • Sinif adları böyük harf, dəyişənlər və kiçik adlarla metod adları ilə başlanır.

Nə olursa olsun, Win16 / Win32 Macar notation istifadə etməyin. Hətta Microsoft bunu .NET platformasına keçməklə tərk etdi.

108
01 окт. Chris Hanson tərəfindən verilmiş cavab Oct 01 2008-10-01 18:47 '08 saat 18:47 'de 2008-10-01 18:47

IBOutlets

Tarixi olaraq, pərakəndə satış yerlərinin yaddaş idarəçiliyi qeyri-qənaətbəxş idi. Mövcud ən yaxşı təcrübə satış vasitələri öz xüsusiyyətləri kimi elan etməkdir:

 @interface MyClass :NSObject { NSTextField *textField; } @property (nonatomic, retain) IBOutlet NSTextField *textField; @end 

Xassələrin istifadəsi yaddaş idarəçiliyinin semantikasını şəffaf edir; Məsələn nümunə dəyişənlərin sintezini istifadə edərkən ardıcıl bir model təmin edir.

107
03 окт. cavab verildi mmalc 03 oktyabr . 2008-10-03 18:43 '08 at 18:43 'da 2008-10-03 18:43

Statik analizatoru LLVM / C>

Qeyd. Xcode 4-də, indi IDE-ə daxil edilir.

C> istifadə edirsiniz - heç bir möcüzə - Mac OS X 10.5-də C kodu və Objective-C (hələ C ++ deyil) analiz edin. Quraşdırmaq və istifadə etmək çox vacibdir:

  • Bu səhifənin son versiyasını yükləyin.
  • cd əmr xəttindən layihə qovluğuna.
  • scan-build -k -V xcodebuild .

(Bəzi əlavə məhdudiyyətlər və s. Var, xüsusən də layihənin Debug konfiqurasiyasında təhlil etməlisiniz - ətraflı məlumat üçün http://c> səhifəsinə baxın) - lakin bu çox və ya azdır nə gəlir.)

Daha sonra, analizator sizin üçün bir sıra veb səhifələr yaradır, bu, ehtimal olunan yaddaş idarəçiliyini və kompilyatorun aşkarlanmadığı digər əsas problemləri göstərir.

04 окт. cavab 04 oktyabr ayına qədər verilir . 2008-10-04 08:15 '08 saat 08:15 'da 2008-10-04 08:15

İncə, lakin rahatdır. Özünüzü başqa bir obyektin nümayəndəsi kimi köçürdüyünüzdə, bu obyektin nümayəndəsi dealloc .

 - (void)dealloc { self.someObject.delegate = NULL; self.someObject = NULL; // [super dealloc]; } 

Bunu edərək, daha çox nümayəndə üsulları göndərilməyəcəyini təmin edirsiniz. Bir dealloc etmək və havada dealloc , heç bir şey qəza ilə daha çox mesaj göndərə bilər əmin etmək istəyirəm. Self.someObject başqa bir obyekt (bir singleton və ya avtomatik reklam hovuzu və ya başqa bir şey ola bilər) tərəfindən saxlanıla biləcəyini və "mənə mesaj göndərməyi dayandırın!" Deyənədək, o, obyektin azad edilməsini düşündüyünü xatırlayın icazəsiz girişdən ədalətli oyun.

Bu vərdişə daxil olmaq, sizi səhvən qəzaya səbəb olan bir çox qəzadan xilas edəcək.

Eyni prinsip əsas dəyər və NSNotifications nəzarət edir.

Düzenle:

Daha qoruyucu, dəyişiklik:

 self.someObject.delegate = NULL; 

in

 if (self.someObject.delegate == self) self.someObject.delegate = NULL; 
95
01 окт. Cavab 01 oktyabr ayına verilir . 2008-10-01 07:59 '08 at 07:59 'da 2008-10-01 07:59

@ kendell

Bunun əvəzinə:

 @interface MyClass (private) - (void) someMethod - (void) someOtherMethod @end 

İstifadə edin:

 @interface MyClass () - (void) someMethod - (void) someOtherMethod @end 

Yeni Objective-C 2.0.

Dərslər üçün uzadılması "Apple Objective-C 2.0 Reference" da təsvir edilmişdir.

"Sınıf uzantıları, əsas @ sinif sinifinin blokundan başqa yerlərdə bir sinif üçün əlavə API bildirməyinizə imkan verir"

Beləliklə, onlar sinfi kateqoriyasındakı bir kateqoriyadan ibarətdir - və NOT (qapalı). İncə, ancaq əhəmiyyətli bir fərq.

87
01 окт. Cavab 01 oktyabr ayına verilir . 2008-10-01 06:53 '08 saat 06:53 'da 2008-10-01 06:53

Avtomatik yeniləmələri çəkinin

Ümumiyyətlə (1) həyatınızın üzərində birbaşa nəzarət olmadığı üçün avtomatik həyata keçən obyektlər nisbətən uzun müddət davam edə bilər və lazımsız şəkildə tətbiqinizin yaddaşını artıra bilər. Masaüstündə çox az məsələ olsa da, məhdud platformalarda bu ciddi problem ola bilər. Buna görə, bütün platformalarda və xüsusilə daha məhdud platformalarda avtomatik tətbiq olunan obyektlərə gətirib çıxaran metodlardan istifadə etməmək üçün ən yaxşı təcrübə hesab olunur və bunun yerine, alloc / init modelini istifadə etməyə təşviq olunur.

Beləliklə, əvəzinə:

 aVariable = [AClass convenienceMethod]; 

mümkün olduqda, istifadə etməlisiniz:

 aVariable = [[AClass alloc] init]; // do things with aVariable [aVariable release]; 

Yeni yaradılmış bir obyekti öz metodlarını yazdığınız zaman alıcının "yeni" adına metod adını əlavə etməklə azad edilməsini qeyd etmək üçün Kakao adlandırma konvensiyasından istifadə edə bilərsiniz.

Beləliklə, əvəzinə:

 - (MyClass *)convenienceMethod { MyClass *instance = [[[self alloc] init] autorelease]; // configure instance return instance; } 

Yaza bilərsiniz:

 - (MyClass *)newInstance { MyClass *instance = [[self alloc] init]; // configure instance return instance; } 

Metodun adının "yeni" ilə başlandığı üçün, API istifadəçiləriniz, ortaya çıxan obyektin azad edilməsindən məsuliyyət daşıyırlar (məsələn, NSObjectController newObject ).

(1) Yerli autodetection havuzlarını istifadə edərək nəzarət ala bilərsiniz. Bununla əlaqədar daha ətraflı məlumat üçün Avtomatik yeniləmə hovuzlarına baxın .

75
06 окт. Cavab verildi 2008-10-06 22:45 '08 at 22:45 2008-10-06 22:45

Bəziləri onsuz da xatırlanıb, amma burada başımı düşünə bilərəm:

  • KVO adlandırma qaydalarına əməl edin. İndi KVO'yu istifadə etmirsinizsə belə, mənim təcrübəmdə bu dəfə də gələcəkdə hələ də faydalıdır. KVO-nu və ya bağlamadan istifadə etsəniz, hər şeyin lazım olan şəkildə işlədiyini bilmək lazımdır. Bu, yalnız metodlara və nümunə dəyişənlərə daxil olmaq üçün deyil, bir çox əlaqələr, doğrulama yoxlamaları, asılı açarların avtomatik bildirişi və s.
  • Bir kateqoriyada xüsusi metodlar qoyun. Yalnız interfeys deyil, həm də tətbiq. Şəxsi və qeyri-özəl üsullar arasında bir məsafədən konseptual olmaq yaxşıdır. Hər şeyi .m faylına daxil edirəm.
  • Bir kateqoriyada fon axınını yerləşdirin. Yuxarıda olduğu kimi. Mən əsas mövzuda olan və nə olmadığı barədə düşünərkən aydın bir konseptual maneəni qoruduğumu gördüm.
  • #pragma mark [section] istifadə edin #pragma mark [section] . Mən adətən öz üsullarımı qruplaşdırıram, hər bir alt sinif hər hansı informasiya və ya rəsmi protokolları yenidən müəyyənləşdirir. Bu mənim aradığım şeyə keçidini asanlaşdırır. Eyni mövzuda, qrupun oxşar metodları (məsələn, masa baxımından nümayəndələrin metodları) onlara uyğun gəlmir.
  • Prefiks ilə xüsusi üsullar və ikonlar. Göründüyü kimi xoşuma gəlir, mən təsadüfən mülkiyyətə gəldiyim zaman İvarı istifadə etməyə daha az güman edirəm.
  • Init və dealloc mutator üsulları / xüsusiyyətləri istifadə etməyin. Mən bu barədə pis bir şey olmamışdım, amma metodunuzu obyektinizin vəziyyətindən asılı bir şey etmək üçün dəyişdirsəniz məntiqini görə bilərik.
  • IBOutletləri xassələrə qoyun. Mən, həqiqətən, burada oxuyuram, amma bunu etməyə başlayacağam. Yaddaşın üstünlüklərindən asılı olmayaraq, stilist baxır (ən azı mənim üçün).
  • Lazım olmayan kod yazmaqdan çəkinin. . Bu, həqiqətən, bir çox şeyləri əhatə edir, məsələn, #define yerinə yetirildikdə ivars yaratmaq və ya hər dəfə məlumatın lazım olduğunu yoxlamaq üçün bir sıra caching. Bunu söyləyə bilərəm, ancaq alt xətt sizə lazım olana qədər kodu yazmır və ya profiler sizə deyir. Bu, uzun müddətli işi asanlaşdırır.
  • Başladığınız şeyi tamamlayın. Bitmiş kodun yarısı çox olsa da, ərizə kodu bir layihəni öldürmənin ən sürətli yolu. Yaxşı olacağınız bir kötük metoduna ehtiyac varsa, yalnız NSLog( @"stub" ) daxil edin və ya hər şeyi izləmək istəyirik.
70
18 нояб. Cavab 18 noyabrda Marc Charbonneau tərəfindən verilir. 2008-11-18 02:11 '08 at 2:11 pm 2008-11-18 02:11

Birlik testlərini yaz. Kokoada bir çox şeyi sınayaraq digər çərçivələrdə daha çətin ola bilər. Məsələn, UI kodu ilə, adətən, hər şeyin olduğu kimi bağlı olduğunu və istifadə edildikdə işləməyəcəyinə əmin ola bilərsiniz. Və asanlıqla dövlət qurmaq və onları yoxlamaq üçün nümayəndə üsulları zəng edə bilərsiniz.

Ayrıca, ictimaiyyətə qarşı görünürlüğünüz yoxdur. qorunur vs daxili komponentləriniz üçün yazılı testləri maneə törədən xüsusi üsul.

56
01 окт. Chris Hanson tərəfindən verilmiş cavab Oct 01 2008-10-01 11:04 '08 at 11:04 2008-10-01 11:04

Qızıl qayda: siz alloc zaman release edirsiniz!

YENİLƏNİB: ARC istifadə etmirsinizsə

55
01 окт. JamesSugrue tərəfindən verilmiş cavab Oct 01 2008-10-01 05:16 '08 saat 05:16 'da 2008-10-01 05:16

Objective-C kimi Java / C # / C ++ / və s. Kimi yazmayın.

Bir zamanlar bir Cocoa masaüstü proqramı yazmağa çalışan bir Java EE web proqram yazmaq üçün istifadə olunan bir komandanı gördüm. Bu bir Java EE veb tətbiqi kimi. FooFactory və FooFactory və IFoo və Foo bir çox mücərrəd var idi, onlar həqiqətən Foo sinifinə və ehtimal ki Fooable protokoluna ehtiyac duydular.

Bunu etməməyinizin bir hissəsi dil dilindəki fərqləri anlamaqdır. Məsələn, müdavim sinflərə fabrik və fabrikə ehtiyac yoxdur, çünki Objective-C sinif metodları dinamik olaraq nümunəvi üsullarla göndərilir və alt siniflərdə əvəz edilə bilər.

55
01 окт. Chris Hanson tərəfindən verilmiş cavab Oct 01 2008-10-01 18:40 '08 at 18:40 2008-10-01 18:40

"Kakao səhvinin mənbəyini tapmaq üçün" başınızı duvara vurduğunuzda ilk stopunuz olmalıdır.

Məsələn, o, ilk növbədə qəzaların yaranmasına səbəb olan (məsələn, ərizənin ləğv edilməsi zamanı) yaddaşın hansı metoddan istifadə etdiyini öyrənəcəkdir.

50
01 окт. cavab mj1531 01 oktyabr verilir . 2008-10-01 19:35 '08 at 7:35 pm 2008-10-01 19:35

İndi Newbiecategaholism'i çağırmağa qərar verdiklərimdən çəkinməyə çalışın. Objective-C-də yeni başlayanlar kategoriyanı aşkar etdikdə, hər bir mövcud sinifə faydalı kiçik kateqoriyalar əlavə edirlər ("Nə? Mən NSNumber rock nömrələrinə ədədi çevirmək üçün bir üsul əlavə edə bilərsiniz!").

Bunu etməyin.

Kodunuz iki düzəldilmiş əsas siniflər üzərində dağılmaq mümkün olan onlarla üsulla daha portativ və daha aydın olacaqdır.

Çox hallarda, həqiqətən, bəzi kodları yaxşılaşdırmağa kömək edəcək bir kateqoriya metoduna ehtiyacı olduğunuzu düşündüyünüz zaman, bu üsulu heç vaxt təkrar istifadə etməyəcəksiniz.

Kateqoriya metodunuzun adlarını istifadə etmirsinizsə (və hiyləgər ddribin kimdən başqa) istifadə etmirsinizsə, başqa bir təhlükə var? Apple, ya da bir plugin və ya başqa bir yerdə ünvanı məkanda işləyən bir ehtimal varsa, eyni kateqoriyadan olan metodu da müəyyən edəcək bir az fərqli yan təsiri ilə eyni adı ilə ....

Tamam İndi xəbərdarlıq etdiyinizə görə "bu hissəni etməyin." Ancaq həddindən artıq maneə törətmək.

38
01 окт. Cavab 01 oktyabr ayına verilir . 2008-10-01 08:16 '08 at 08:16 2008-10-01 08:16

İstifadəçi tərəfindən satırları sıralayın

Istifadəçi üçün təqdimat üçün simləri sıraladığınızda, sadə compare: üsulunu istifadə etməyin compare: metodu. Bunun əvəzində, localizedCompare: və ya localizedCaseInsensitiveCompare: kimi localizedCompare: müqayisə üsullarından istifadə etməlisiniz.

Daha ətraflı məlumat üçün , arayın, müqayisə edin və satırları sıralayın .

38
06 окт. Cavab verildi 2008-10-06 19:49 '08 at 7:49 PM 2008-10-06 19:49

Dünyaya subclassing müqavimət. Kakaoda, nümayəndə heyəti vasitəsilə baş verən və digər çərçivələrdə bir alt sinif vasitəsilə həyata keçirilən əsas iş vaxtından çox istifadə edilir.

Məsələn, Java-da tez-tez anonim *Listener alt sinif EventArgs istifadə EventArgs , və. NET-də tez-tez EventArgs alt siniflərindən istifadə EventArgs . Cocoa'da da yerinə yetirilmirsiniz: hədəf hərəkət yerinə istifadə edilir.

37
01 окт. Chris Hanson tərəfindən verilmiş cavab Oct 01 2008-10-01 11:10 '08 at 11:10 2008-10-01 11:10

Təklif olunan xassələr

Tipik olaraq, bütün xüsusiyyətləriniz üçün Objective-C 2.0 elan funksiyası funksiyasından istifadə etməlisiniz. Əgər onlar ictimaiyyətə açıq deyilsə, onları sinfi uzantısına əlavə edin. Bildirilmiş xassələri istifadə edərək, yaddaş idarəçiliyinin semantikasını asanlaşdırır və dealloc metodunuzun doğrulmasını asanlaşdırır - əmlak bəyannamələrini birləşdirsəniz, onları tez bir zamanda tarayaraq, dealloc metodunuzun tətbiqi ilə müqayisə edə bilərsiniz.

Mətnləri "qeyri-təbii" kimi göstərməmişdən əvvəl çox düşünmək məcburiyyətindəsiniz. Objective-C proqramlaşdırma dilində qeydlər olduğundan, default xüsusiyyətləri atomdur və əhəmiyyətli yük daşımır. Üstəlik, sadəcə bütün xüsusiyyətlərinizi atomik hala gətirmək, tətbiqinizin işini təhlükəsiz etmir. Также обратите внимание, конечно, что если вы не укажете "неатомические" и не реализуете свои собственные методы доступа (вместо их синтезирования), вы должны реализовать их по-атомному.

31
ответ дан mmalc 03 окт. '08 в 18:51 2008-10-03 18:51

Подумайте о значениях nil

Как этот вопрос , сообщения nil действительны в Objective-C. Хотя это часто является преимуществом, что приводит к более чистому и более естественному коду, функция может иногда приводить к сложным и сложным ошибкам, если вы получаете значение nil , когда вы этого не ожидали.

26
ответ дан mmalc 12 окт. '08 в 23:14 2008-10-12 23:14

Используйте NSAssert и друзей. Я использую nil как действительный объект все время... особенно отправка сообщений в nil отлично действует в Obj-C. Однако, если я действительно хочу убедиться в состоянии переменной, я использую NSAssert и NSParameterAssert, что помогает легко отслеживать проблемы.

26
ответ дан NikWest 07 мая '09 в 23:57 2009-05-07 23:57

Простая, но забытая. Согласно спецификации:

В общем, методы в разных классы, которые имеют один и тот же селектор (одно и то же имя) также должны одинаковые типы возвратов и аргументов. Эта ограничение накладывается компилятором для динамического связывания.

и в этом случае все одинаковые именованные селектора , даже если в разных классах , будут считаться одинаковыми типами возвращаемых/аргументов. Burada sadə bir nümunədir.

 @interface FooInt:NSObject{} -(int) print; @end @implementation FooInt -(int) print{ return 5; } @end @interface FooFloat:NSObject{} -(float) print; @end @implementation FooFloat -(float) print{ return 3.3; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; id f1=[[FooFloat alloc]init]; //prints 0, runtime considers [f1 print] to return int, as f1 type is "id" and FooInt precedes FooBar NSLog(@"%f",[f1 print]); FooFloat* f2=[[FooFloat alloc]init]; //prints 3.3 expectedly as the static type is FooFloat NSLog(@"%f",[f2 print]); [f1 release]; [f2 release] [pool drain]; return 0; } 
23
ответ дан Özgür 27 авг. '10 в 13:17 2010-08-27 13:17

Если вы используете Leopard (Mac OS X 10.5) или более позднюю версию, вы можете использовать приложение "Инструменты" для поиска и отслеживания утечек памяти. После создания вашей программы в Xcode выберите "Выполнить" > "Начать работу с инструментом производительности" > "Утечки".

Даже если ваше приложение не показывает никаких утечек, вы можете слишком долго хранить объекты. В Инструментах для этого вы можете использовать инструмент ObjectAlloc. Выберите инструмент ObjectAlloc в документе "Инструменты" и вызовите деталь инструмента (если он еще не отображается), выбрав "Просмотр" > "Подробно" (рядом с ним должна быть отметка). В разделе "Распределение продолжительности жизни" в деталях ObjectAlloc убедитесь, что вы выбрали переключатель рядом с "Созданный и неподвижный".

Теперь, когда вы прекращаете запись своего приложения, выбирая инструмент ObjectAlloc, вы покажете, сколько ссылок есть на каждый неподвижный объект в вашем приложении в столбце "# Net". Убедитесь, что вы не только просматриваете свои собственные классы, но и классы ваших объектов верхнего уровня NIB файлов. Например, если у вас нет окон на экране, и вы видите ссылки на все еще живое NSWindow, возможно, вы не выпустили его в свой код.

22
ответ дан mj1531 01 окт. '08 в 19:57 2008-10-01 19:57

Очистка в dealloc.

Это одна из самых простых вещей, которые нужно забыть - особенно. при кодировании со скоростью 150 миль в час. Всегда, всегда, всегда очищайте свои атрибуты/переменные-члены в dealloc.

Мне нравится использовать атрибуты Objc 2 - с новой точечной нотацией, поэтому это делает очистку безболезненной. Часто так же просто, как:

 - (void)dealloc { self.someAttribute = NULL; [super dealloc]; } 

Это позаботится о выпуске для вас и установит атрибут в NULL (который я считаю защитным программированием), если другой метод еще дальше в dealloc снова получит доступ к переменной-члену - редко, но может произойти).

Когда GC включен в 10.5, это больше не нужно, но вам все равно нужно очистить другие ресурсы, которые вы создаете, но вы можете сделать это в методе finalize.

21
ответ дан schwa 01 окт. '08 в 7:54 2008-10-01 07:54

Все эти комментарии замечательные, но я действительно удивлен, что никто не упоминал Google Objective-C Руководство по стилю , которое было опубликовано некоторое время назад. Я думаю, что они проделали очень тщательную работу.

17
ответ дан slf 16 дек. '08 в 22:27 2008-12-16 22:27
15
ответ дан schwa 01 окт. '08 в 8:31 2008-10-01 08:31

Не забывайте, что NSWindowController и NSViewController освободят объекты верхнего уровня файлов NIB, которые они определяют.

Если вы вручную загружаете файл NIB, вы несете ответственность за освобождение объектов верхнего уровня NIB, когда вы закончите с ними.

13
ответ дан mj1531 01 окт. '08 в 20:02 2008-10-01 20:02

Один довольно очевидный для новичков: используйте функцию автодементации Xcode для вашего кода. Даже если вы копируете/вставляете из другого источника, после того, как вы вставили код, вы можете выбрать весь блок кода, щелкнуть правой кнопкой мыши по нему, а затем выбрать вариант для повторного отступов всего внутри этого блока.

Xcode фактически проанализирует этот раздел и отступ, основанный на скобках, циклах и т.д. Это намного эффективнее, чем ударить пробел или клавишу табуляции для каждой строки.

12
ответ дан iwasrobbed 12 июля '10 в 22:09 2010-07-12 22:09

Переменные и свойства

1/Сохранение заголовков в чистоте, скрытие реализации
Не включайте переменные экземпляра в свой заголовок. Частные переменные помещаются в класс как свойства. Публичные переменные объявляют как публичные свойства в вашем заголовке. Если он должен быть только прочитан, объявите его как readonly и перезапишите его как readwrite в непрерывном классе. В основном я вообще не использую переменные, только свойства.

2/Дайте вашим свойствам имя переменной, отличное от значения по умолчанию, например:

 @synthesize property = property_; 

Причина 1: вы поймаете ошибки, вызванные забыванием "я". при назначении свойства. Причина 2: Из моих экспериментов Leak Analyzer в Инструментах имеет проблемы с обнаружением свойства утечки с именем по умолчанию.

3/Никогда не используйте удержание или выпуск непосредственно по свойствам (или только в исключительных ситуациях). В вашем dealloc просто назначьте им нуль. Сохраняемые свойства предназначены для самостоятельной обработки удержания/выпуска. Вы никогда не знаете, нет ли сеттера, например, добавление или удаление наблюдателей. Вы должны использовать переменную непосредственно только внутри своего сеттера и получателя.

Просмотры

1/Поместите каждое представление в xib, если вы можете (исключение - это обычно динамический контент и настройки слоя). Это экономит время (это проще, чем написание кода), его легко изменить, и он сохраняет ваш код в чистоте.

2/Не пытайтесь оптимизировать представления, уменьшая количество просмотров. Не создавайте UIImageView в коде вместо xib только потому, что вы хотите добавить в него subviews. Вместо этого используйте UIImageView. Структура представления может обрабатывать сотни представлений без проблем.

3/IBOutlets не обязательно всегда сохраняться (или сильным). Обратите внимание, что большинство ваших IBOutlets являются частью вашей иерархии представлений и поэтому неявно сохраняются.

4/Отпустите все IBOutlets в viewDidUnload

5/Вызов viewDidUnload из вашего метода dealloc. Это неявно называется.

Память

1/Объекты Autorelease при их создании. Многие ошибки вызваны перемещением вашего запроса на выпуск в одну ветвь if-else или после оператора return. Выпуск вместо автореферата должен использоваться только в исключительных ситуациях - например, когда вы ожидаете runloop, и вы не хотите, чтобы ваш объект был автореализован слишком рано.

2/Даже если вы используете Authomatic Reference Counting, вы должны прекрасно понимать, как работают методы удержания. Использование сохранения-освобождения вручную не сложнее, чем ARC, в обоих случаях вы должны разбираться в утечках и циклах сохранения. Рассмотрите возможность использования сохранения-выпуска вручную в больших проектах или сложных иерархиях объектов.

Комментарии

1/Сделайте свой код автодокументированным. Каждое имя переменной и имя метода должны указывать, что он делает. Если код написан правильно (вам нужно много практики в этом), вам не понадобятся комментарии коментариев (не то же самое, что и комментарии к документации). Алгоритмы могут быть сложными, но код всегда должен быть простым.

2/Иногда вам нужен комментарий. Обычно описывать поведение, не являющееся очевидным кодом, или взломать. Если вы чувствуете, что вам нужно написать комментарий, сначала попробуйте переписать код, чтобы он был проще и без комментариев.

Отступ

1/Не увеличивайте отступ слишком сильно. Большая часть вашего кода метода должна быть отступом на уровне метода. Вложенные блоки (если, для и т.д.) Уменьшают читаемость. Если у вас есть три вложенных блока, вы должны попытаться поместить внутренние блоки в отдельный метод. Четыре или более вложенных блоков никогда не должны использоваться. Если большая часть вашего кода метода находится внутри if, отрицайте условие if, например:

 if (self) { //... long initialization code ... } return self; 
 if (!self) { return nil; } //... long initialization code ... return self; 

Понять код C, в основном C structs

Обратите внимание, что Obj-C является только легким слоем OOP над языком C. Вы должны понимать, как работают базовые структуры кода в работе C (перечисления, структуры, массивы, указатели и т.д.). Məsələn:

 view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20); 

совпадает с:

 CGRect frame = view.frame; frame.size.height += 20; view.frame = frame; 

И многое другое

Предоставьте свой собственный документ стандартов кодирования и часто его обновляйте. Попробуйте учиться на своих ошибках. Поймите, почему была создана ошибка, и старайтесь избегать ее, используя стандарты кодирования.

Наши стандарты кодирования имеют в настоящее время около 20 страниц, сочетание стандартов кодирования Java, стандартов Google Obj-C/С++ и наших собственных дополнений. Документируйте свой код, используйте стандартные стандартные отступы, пробелы и пустые строки в нужных местах и ​​т.д.

10
ответ дан Sulthan 19 окт. '11 в 5:58 2011-10-19 05:58

Включите все предупреждения GCC, затем отключите те, которые регулярно вызываются заголовками Apple, чтобы снизить уровень шума.

Также часто выполняйте статический анализ C>

Напишите модульные тесты и запустите их с каждой сборкой.

10
ответ дан oefe 18 окт. '09 в 21:12 2009-10-18 21:12

Я знаю, что я пропустил это при первом входе в программирование Cocoa.

Убедитесь, что вы понимаете ответственность за управление памятью в отношении файлов NIB. Вы несете ответственность за освобождение объектов верхнего уровня в любом загружаемом файле NIB. Прочитайте Документация Apple по этому вопросу.

10
ответ дан mj1531 01 окт. '08 в 19:19 2008-10-01 19:19

Быть более функциональным .

Objective-C - это объектно-ориентированный язык, но Cocoa функциональный стиль фреймворка и во многих случаях разработан функциональный стиль.

  • Существует разделение изменчивости. Используйте неизменяемые классы как первичные, а изменчивый объект - как вторичный. Например, сначала используйте NSArray и используйте NSMutableArray только тогда, когда вам нужно.

  • Существуют чистые функции. Не так много, купите многие из API-интерфейсов инфраструктуры, разработанных как чистая функция. Посмотрите на функции, такие как CGRectMake() или CGAffineTransformMake() . Очевидно, что форма указателя выглядит более эффективной. Однако косвенный аргумент с указателями не может обеспечить побочный эффект. Конструктивные конструкции максимально в максимально возможной степени. Разделяйте даже объекты состояния. Используйте -copy вместо -retain при передаче значения другому объекту. Поскольку совместное состояние может влиять на мутацию, чтобы значение в другом объекте было тихо. Таким образом, не может быть побочным эффектом. Если у вас есть значение от внешнего объекта, скопируйте его. Таким образом, это также важно для разработки общего состояния как можно более минимального.

Однако не бойтесь использовать нечистые функции.

  • Существует ленивая оценка. Посмотрите что-то вроде свойства -[UIViewController view] . Представление не будет создано при создании объекта. Он будет создан, когда вызывающий абонент читает свойство view в первый раз. UIImage не будет загружаться до фактического рисования. Существует много реализаций, подобных этой конструкции. Подобные проекты очень полезны для управления ресурсами, но если вы не знаете понятия ленивой оценки, нелегко понять их поведение.

  • Существует закрытие. Используйте C-блоки как можно больше. Это значительно упростит вашу жизнь. Но прочитайте еще раз об управлении блочной памятью, прежде чем использовать его.

  • Существует полуавтоматический GC. NSAutoreleasePool. Используйте -autorelease primary. Используйте ручную -retain/-release вторичную, когда вам действительно нужно. (например: оптимизация памяти, явное удаление ресурсов)

9
ответ дан Eonil 29 марта '11 в 20:51 2011-03-29 20:51
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос