मैंने कई डेवलपर्स को देखा है जो अपने iOS प्रोजेक्ट्स के Prefix.pch में विभिन्न सुविधा मैक्रो जोड़ते हैं।
आप iOS Prefix.pch फ़ाइल में जोड़ने की क्या सलाह देते हैं (या नहीं)? आपका Prefix.pch कैसा दिखता है?
मैंने कई डेवलपर्स को देखा है जो अपने iOS प्रोजेक्ट्स के Prefix.pch में विभिन्न सुविधा मैक्रो जोड़ते हैं।
आप iOS Prefix.pch फ़ाइल में जोड़ने की क्या सलाह देते हैं (या नहीं)? आपका Prefix.pch कैसा दिखता है?
Macros.h
, अपने मैक्रोज़ को हेडर फ़ाइल में रखें , और फिर इस फ़ाइल को अपने में आयात करें prefix.pch
।
जवाबों:
Ewww… .pch फ़ाइल में मैक्रोज़ न डालें! .Pch फ़ाइल, परिभाषा के अनुसार, एक परियोजना विशिष्ट पूर्वनिर्धारित हेडर है। यह वास्तव में परियोजना के संदर्भ से परे इस्तेमाल नहीं किया जाना चाहिए और इसमें वास्तव में कुछ भी नहीं होना चाहिए लेकिन #include
एस और #import
एस।
यदि आपके पास कुछ मैक्रोज़ हैं और आप हेडर के बीच साझा करना चाहते हैं, तो उन्हें अपने स्वयं के हेडर फ़ाइल में चिपकाएँ - Common.h
या जो कुछ भी है - और #include
जो कि .pch की शुरुआत में है।
आधुनिक आईओएस और ओएस एक्स के लिए, लोगों को मॉड्यूल का उपयोग करना चाहिए । यह नई परियोजनाओं के लिए डिफ़ॉल्ट रूप से सक्षम है, और आयात / शामिल करने का उपयोग करके पूरा किया जाता है @import
।
मॉड्यूल एक मॉड्यूल की सामग्री का एक मध्यवर्ती प्रतिनिधित्व (उदाहरण के लिए एक रूपरेखा के हेडर) बनाने के लिए संकलक की अनुमति देता है। एक PCH की तरह, इस मध्यवर्ती प्रतिनिधित्व को कई अनुवादों में साझा किया जा सकता है। लेकिन मॉड्यूल इसे एक कदम आगे ले जाते हैं क्योंकि एक मॉड्यूल आवश्यक रूप से विशिष्ट लक्ष्य नहीं है, और उनकी घोषणाओं को स्थानीयकृत (ए *.pch
) करने की आवश्यकता नहीं है । यह प्रतिनिधित्व आपको एक टन निरर्थक संकलक कार्य बचा सकता है।
मॉड्यूल का उपयोग करना, आपको पीसीएच की आवश्यकता नहीं है, और आपको शायद पूरी तरह से उनके साथ दूर करना चाहिए - @import
निर्भरता के लिए स्थानीय का उपयोग करने के पक्ष में । उस स्थिति में, एक PCH केवल निर्भरता के लिए स्थानीय (जो आपको IMO वैसे भी होना चाहिए) समावेशी टाइपिंग से बचा रहा है।
अब, यदि हम मूल प्रश्न पर पीछे मुड़कर देखते हैं: आपको अपने पीसीएच को सभी प्रकार की यादृच्छिक चीजों से भरने से बचना चाहिए; मैक्रों, स्थिरांक, #defines
और छोटे पुस्तकालयों के सभी प्रकार। आम तौर पर, आपको अपने स्रोत फ़ाइलों के बहुमत के लिए वास्तव में अनावश्यक है , इसे छोड़ देना चाहिए । अपने पीसीएच में सभी प्रकार के सामान डालना सिर्फ वजन और निर्भरता का एक गुच्छा जोड़ रहा है। मैं देखता हूं कि लोग पीसीएच में सब कुछ लिंक करते हैं और बहुत कुछ करते हैं। वास्तव में, सहायक ढांचे को आमतौर पर केवल ज्यादातर मामलों में कुछ अनुवादों के लिए दिखाई देने की आवश्यकता होती है। जैसे “यहाँ हमारा StoreKit सामान है - चलिए StoreKit को केवल वहीं आयात करें जहाँ यह होना चाहिएदिखाई देना। विशेष रूप से, ये 3 अनुवाद "। यह आपके बिल्ड समय को कम रखता है, और आपको अपनी निर्भरता पर नज़र रखने में मदद करता है, ताकि आप कोड को अधिक आसानी से पुन: उपयोग कर सकें। इसलिए एक ओबीजीसी परियोजना में, आप आमतौर पर फाउंडेशन पर रुक जाएंगे। यदि बहुत कुछ है। UI, तो आप अपने PCH में UIKit या AppKit जोड़ने पर विचार कर सकते हैं। यह सब मान रहा है कि आप बिल्ड समय का अनुकूलन करना चाहते हैं। बड़े PCH के साथ समस्याओं में से एक जिसमें (लगभग) सब कुछ शामिल है, अनावश्यक निर्भरता को दूर करने में बहुत समय लगता है। आपकी परियोजना की निर्भरताएँ बढ़ती हैं और आपका निर्माण समय बढ़ता जाता है, आपको अपने निर्माण समय को कम करने के लिए अनावश्यक निर्भरता को समाप्त करके वापस लड़ने की आवश्यकता होती है। PCHs साझा करने के लिए कुछ विकल्प हैं। यदि आप PCHs का उपयोग करते हैं,
जहाँ तक मैंने अपने PCH में रखा है: मैंने वर्षों पहले लक्ष्य के विशाल बहुमत के लिए उनका उपयोग करना बंद कर दिया था। वहाँ आम तौर पर अर्हता प्राप्त करने के लिए पर्याप्त नहीं है। ध्यान में रखते हुए, मैं C ++, ObjC, ObjC ++ और C लिखता हूं - संकलक आपके लक्ष्य में प्रत्येक लैंग के लिए एक का उत्सर्जन करता है। इसलिए उन्हें सक्षम करने से अक्सर धीमी गति के समय और उच्चतर I / O हो जाते हैं। अंततः, बढ़ती निर्भरता जटिल परियोजनाओं में निर्भरता से लड़ने का एक अच्छा तरीका नहीं है। कई भाषाओं / बोलियों के साथ काम करना, किसी दिए गए लक्ष्य के लिए आवश्यक निर्भरता में बहुत भिन्नता है। नहीं, मैं सलाह नहीं दूंगा कि हर परियोजना के लिए इष्टतम, लेकिन यह बड़ी परियोजनाओं में निर्भरता प्रबंधन के लिए कुछ दृष्टिकोण देता है।
संदर्भ
टिप्पणियाँ
#import "MyLib/MyLib.h"
:। किसी भी समय MyLib.h
परिवर्तन द्वारा शामिल की गई फ़ाइल, ऐप में मौजूद प्रत्येक स्रोत फ़ाइल को फिर से स्थापित किया जाना चाहिए। यदि आप MyLib का उपयोग केवल एक स्रोत फ़ाइल में करते हैं, तो MyLib में परिवर्तन होने पर केवल उस फ़ाइल को फिर से इंस्टॉल किया जाना चाहिए। मानो या न मानो, मैं इन दिनों किसी भी PCH फ़ाइलों का उपयोग नहीं कर रहा हूँ।
मैं बीबूम के साथ सहमत हूं। पीसीएच फाइल पर मेरा कहना है कि इसमें बहुत अधिक #include
या केवल #import
कथन होने चाहिए। इसलिए यदि आपके पास सहायक, उच्च-स्तरीय मैक्रोज़ का एक गुच्छा है, तो उन्हें कुछ Common.h
और #import
उस फ़ाइल में परिभाषित करें , जैसा कि bbum ने सुझाव दिया है।
मैं आमतौर पर एक कदम और आगे जाने के लिए और करने के लिए PCH फ़ाइल का उपयोग #import
नामक एक फ़ाइल XXCategories.h
(जहां XX
कि है जिसका उपयोग वर्ग नामकरण उपसर्ग सम्मेलन है) #import
मेरे सभी UIKit और फाउंडेशन वर्ग श्रेणियों के लिए रों: NSString+XXAdditions.h
, UIColor+XXAdditons.h
, आदि
#import
और सिर्फ #import
सीधे आयात करने वाले हैं? क्या वे समान नहीं होंगे ?, या क्या यह किसी प्रदर्शन को प्रभावित करता है?
#import
और के लिए होना चाहिए #include
।
एक हेडर फ़ाइल बनाएं "macros.h"
इस शीर्ष लेख को Prefix.pch में आयात करें
इस macros.h में सभी चौखटे और अन्य महत्वपूर्ण चीजें डालते हैं।
यदि आप प्रदर्शन के बारे में चिंतित हैं, तो चिंता न करें, देखें कि सेब क्या कहता है:
हेडर और प्रदर्शन
यदि आप चिंतित हैं कि मास्टर हेडर फ़ाइल सहित आपके प्रोग्राम को ब्लोट हो सकता है, तो चिंता न करें। क्योंकि OS X इंटरफेस को फ्रेमवर्क का उपयोग करके कार्यान्वित किया जाता है, उन इंटरफेस के लिए कोड एक गतिशील साझा पुस्तकालय में रहता है और आपके निष्पादन योग्य में नहीं। इसके अलावा, केवल आपके प्रोग्राम द्वारा उपयोग किए जाने वाले कोड को कभी-कभी रनटाइम में मेमोरी में लोड किया जाता है, इसलिए आपका इन-मेमोरी फ़ुटप्रिंट इसी तरह छोटा रहता है। संकलन के दौरान हेडर फ़ाइलों की एक बड़ी संख्या को शामिल करने के लिए, एक बार फिर, चिंता न करें। Xcode संकलन समय को तेज करने के लिए एक पूर्वनिर्धारित हेडर सुविधा प्रदान करता है। एक ही बार में सभी ढांचे के हेडर को संकलित करके, हेडर को फिर से जोड़ने की आवश्यकता नहीं है जब तक कि आप एक नया ढांचा नहीं जोड़ते हैं। इस बीच, आप शामिल फ़्रेमवर्क से किसी भी इंटरफ़ेस का उपयोग बहुत कम या कोई प्रदर्शन जुर्माना नहीं कर सकते हैं।
मेरे macros.h में भी मैंने बहुत सारे स्थिरांक लगाए हैं:
// delegate
#define UIAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]
#define APPDELEGATE ((AppDelegate *)[[UIApplication sharedApplication] delegate])
// system
#define IS_IPHONE_4INCH (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height==568)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// screen size
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)
#define IS_RETINA_DISPLAY ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))
#define IS_PORTRAIT UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])
#define IS_LANDSCAPE UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])
//system version
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
// math
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))
// cores
#define RGB(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
#define MAKECOLOR(R, G, B, A) [UIColor colorWithRed:((float)R/255.0f) green:((float)G/255.0f) blue:((float)B/255.0f) alpha:A]
#define MAKECOLORFROMHEX(hexValue) [UIColor colorWithRed: ((float)((hexValue & 0xFF0000) >> 16))/255.0 green:((float)((hexValue & 0xFF00) >> 8))/255.0 blue:((float)(hexValue & 0xFF))/255.0 alpha:1.0]
//customizations
#define SHOW_STATUS_BAR [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
#define HIDE_STATUS_BAR [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
#define SHOW_NAVIGATION_BAR [self.navigationController setNavigationBarHidden:FALSE];
#define HIDE_NAVIGATION_BAR [self.navigationController setNavigationBarHidden:TRUE];
#define VC_OBJ(x) [[x alloc] init]
#define VC_OBJ_WITH_NIB(x) [[x alloc] initWithNibName : (NSString *)CFSTR(#x) bundle : nil]
#define RESIGN_KEYBOARD [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
#define CLEAR_NOTIFICATION_BADGE [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
#define REGISTER_APPLICATION_FOR_NOTIFICATION_SERVICE [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]
#define HIDE_NETWORK_ACTIVITY_INDICATOR [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
#define SHOW_NETWORK_ACTIVITY_INDICATOR [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
#define async(...) dispatch_async(dispatch_get_main_queue(), __VA_ARGS__ )
... मुख्य धागे पर ब्लॉक चलाने के लिए:async(^{ self.someLabel.text = @":D"; });