স্ট্যাটিক লাইব্রেরিতে উদ্দেশ্য-সি বিভাগসমূহ


153

আপনি কীভাবে আইটেম প্রকল্পের সাথে স্থির গ্রন্থাগারটি সঠিকভাবে লিঙ্ক করতে পারেন আমাকে গাইড করতে পারেন। আমি অ্যাপ্লিকেশন প্রকল্পে সরাসরি নির্ভরতা (টার্গেট -> সাধারণ -> প্রত্যক্ষ নির্ভরতা) এবং সমস্ত কাজ ঠিক আছে, তবে বিভাগ হিসাবে যুক্ত স্ট্যাটিক লাইব্রেরি প্রকল্প ব্যবহার করি। স্ট্যাটিক লাইব্রেরিতে সংজ্ঞায়িত একটি বিভাগ অ্যাপে কাজ করছে না।

সুতরাং আমার প্রশ্নটি কীভাবে অন্যান্য প্রকল্পে কিছু বিভাগ সহ স্থিতাগুলি যুক্ত করবেন?

এবং সাধারণভাবে, অন্যান্য প্রকল্পগুলির অ্যাপ্লিকেশন কোড কোড ব্যবহার করার জন্য সর্বোত্তম অনুশীলন কোনটি?


1
ভাল, কিছু উত্তর খুঁজে পেয়েছি এবং মনে হয় এই প্রশ্নের ইতিমধ্যে এখানে উত্তর দেওয়া হয়েছে (দুঃখিত এটি মিস করেছেন stackoverflow.com/questions/932856/… )
ভ্লাদিমির

উত্তর:


228

সমাধান: এক্সকোড ৪.২ অনুসারে আপনাকে কেবল অ্যাপ্লিকেশনটিতে যেতে হবে যা লাইব্রেরির সাথে সংযোগ স্থাপন করছে (লাইব্রেরি নিজেই নয়) এবং প্রকল্প ন্যাভিগেটরে প্রকল্পটি ক্লিক করতে হবে, আপনার অ্যাপের লক্ষ্যকে ক্লিক করুন, তারপরে সেটিংস তৈরি করুন, তারপরে "অন্যান্য অনুসন্ধান করুন" লিঙ্কার ফ্ল্যাগস ", + বোতামটি ক্লিক করুন এবং '-ObjC' যুক্ত করুন। '-সমস্ত_লোড' এবং '-ফোর্স_লোড' এর আর দরকার নেই।

বিশদ: আমি বিভিন্ন ফোরাম, ব্লগ এবং অ্যাপল ডক্সে কিছু উত্তর পেয়েছি। এখন আমি আমার অনুসন্ধান এবং পরীক্ষাগুলির সংক্ষিপ্তসার তৈরি করার চেষ্টা করছি।

(অ্যাপল টেকনিক্যাল প্রশ্নোত্তর থেকে QAA QA1490 https://developer.apple.com/library/content/qa/qa1490/_index.html থেকে উদ্ধৃতি দেওয়া ) সমস্যার কারণে দেখা দিয়েছে:

উদ্দেশ্য-সি প্রতিটি ফাংশনের জন্য লিঙ্কার প্রতীক সংজ্ঞায়িত করে না (বা পদ্ধতি, উদ্দেশ্য-সি) - পরিবর্তে, লিঙ্কার চিহ্নগুলি প্রতিটি শ্রেণীর জন্যই তৈরি করা হয়। আপনি যদি বিভাগগুলির সাথে পূর্ব-বিদ্যমান শ্রেণিটি প্রসারিত করেন তবে লিঙ্কার মূল শ্রেণীর প্রয়োগের বিষয়বস্তি কোড এবং বিভাগ বাস্তবায়নের সাথে সংযুক্ত করতে জানেন না। এটি বিভাগে সংজ্ঞায়িত এমন কোনও নির্বাচককে প্রতিক্রিয়া জানাতে ফলস্বরূপ অ্যাপ্লিকেশনটিতে তৈরি বস্তুগুলিকে বাধা দেয়।

এবং তাদের সমাধান:

এই সমস্যাটি সমাধান করার জন্য, স্ট্যাটিক লাইব্রেরির লিঙ্কারের কাছে -ObjC বিকল্পটি পাস করা উচিত। এই পতাকাটির ফলে লিঙ্কার লাইব্রেরির প্রতিটি বস্তু ফাইল লোড করে যা একটি উদ্দেশ্য-সি শ্রেণি বা বিভাগকে সংজ্ঞায়িত করে। এই বিকল্পটির ফলে সাধারণত বৃহত্তর এক্সিকিউটেবল (অ্যাপ্লিকেশনটিতে লোড হওয়া অতিরিক্ত অবজেক্ট কোডের কারণে) ফলাফল আসবে, এটি কার্যকর ক্লাসে বিভাগগুলি সহ কার্যকর কার্যকর উদ্দেশ্য-সি স্ট্যাটিক লাইব্রেরি তৈরির সফল অনুমতি দেবে।

এবং আইফোন বিকাশ এফএকিউতেও সুপারিশ রয়েছে:

স্থির পাঠাগারটিতে আমি কীভাবে সমস্ত উদ্দেশ্য সি-ক্লাসগুলিতে লিঙ্ক করব? অন্যান্য লিঙ্কার ফ্ল্যাগস বিল্ডিং সেটিং -ObjC এ সেট করুন।

এবং পতাকা বর্ণনা:

- all_load স্থিতিশীল সংরক্ষণাগার লাইব্রেরির সমস্ত সদস্যকে লোড করে।

- ওবিজেসি স্ট্যাটিক আর্কাইভ গ্রন্থাগারের সমস্ত সদস্যকে লোড করে যা একটি উদ্দেশ্য-সি শ্রেণি বা বিভাগ প্রয়োগ করে।

- ফোর্স_লোড (পাথ_ টু_আর্কাইভ) নির্দিষ্ট স্ট্যাটিক আর্কাইভ লাইব্রেরির সমস্ত সদস্যকে লোড করে। দ্রষ্টব্য: - সমস্ত_লোড সমস্ত আর্কাইভের সমস্ত সদস্যকে লোড হতে বাধ্য করে। এই বিকল্পটি আপনাকে একটি নির্দিষ্ট সংরক্ষণাগারটিকে টার্গেট করতে দেয়।

* আমরা অ্যাপ্লিকেশন বাইনারি আকার হ্রাস করতে এবং দ্বন্দ্বগুলি এড়াতে বল_লোড ব্যবহার করতে পারি যা কিছু ক্ষেত্রে অল_লোড হতে পারে।

হ্যাঁ, এটি প্রকল্পে যুক্ত * .এ ফাইলগুলির সাথে কাজ করে। তবুও আমার কাছে লাইব প্রকল্পের সাথে প্রত্যক্ষ নির্ভরতা হিসাবে যুক্ত হওয়াতে সমস্যা হয়েছিল। তবে পরে আমি দেখতে পেয়েছি যে এটি আমার দোষ ছিল - সরাসরি নির্ভরতা প্রকল্প সম্ভবত সঠিকভাবে যোগ করা হয়নি। আমি যখন এটি সরিয়ে ফেলি এবং পদক্ষেপগুলি দিয়ে আবার যুক্ত করব:

  1. অ্যাপ্লিকেশন প্রকল্পে lib প্রকল্পের ফাইলটি টানুন এবং ফেলে দিন (বা প্রকল্পের সাথে এটি>> প্রকল্পে যুক্ত করুন ...)।
  2. লাইব প্রকল্প আইকনটিতে তীরটিতে ক্লিক করুন - mylib.a ফাইলের নাম দেখানো হয়েছে, এই mylib.a ফাইলটিকে টেনে আনুন এবং এটিকে টার্গেটে -> লাইব্রেরি গ্রুপের সাথে বাইনারি লিঙ্ক করুন drop
  3. মুষ্টি পৃষ্ঠায় লক্ষ্য তথ্য (সাধারণ) খুলুন এবং নির্ভরযোগ্যতা তালিকায় আমার lib যুক্ত করুন

এর পরে সব ঠিক আছে। "-ObjC" পতাকাটি আমার ক্ষেত্রে যথেষ্ট ছিল।

আমি http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html ব্লগ থেকে ধারণা নিয়ে আগ্রহী ছিলাম । লেখক বলছেন - তিনি সমস্ত-লোড বা -ObjC পতাকা সেট না করেই lib থেকে বিভাগটি ব্যবহার করতে পারেন। তিনি কেবল এইচটি / এম ফাইলগুলিতে ক্যাটাগরি যুক্ত করে খালি ডামি ক্লাস ইন্টারফেস / প্রয়োগকারীকে এই ফাইলটি ব্যবহার করতে বাধ্য করতে to এবং হ্যাঁ, এই কৌশলটি কাজ করে।

তবে লেখক আরও বলেছিলেন যে তিনি এমনকি ডামি অবজেক্টটি ইনস্ট্যান্ট করেননি। মিম ... আমি যেমনটি পেয়েছি আমাদের বিভাগের ফাইল থেকে স্পষ্টভাবে কিছু "আসল" কোড কল করা উচিত। কমপক্ষে ক্লাস ফাংশন বলা উচিত। এবং আমাদের এমনকি ডামি ক্লাসের দরকার নেই। সিঙ্গল সি ফাংশন একই কাজ।

সুতরাং আমরা যদি lib ফাইলগুলি লিখি:

// mylib.h
void useMyLib();

@interface NSObject (Logger)
-(void)logSelf;
@end


// mylib.m
void useMyLib(){
    NSLog(@"do nothing, just for make mylib linked");
}


@implementation NSObject (Logger)
-(void)logSelf{
    NSLog(@"self is:%@", [self description]);
}
@end

এবং যদি আমরা UseMyLib () বলি; অ্যাপ প্রকল্পের যে কোনও জায়গায় তারপর যে কোনও শ্রেণিতে আমরা লগসেলফ বিভাগ বিভাগটি ব্যবহার করতে পারি;

[self logSelf];

এবং থিম সম্পর্কিত আরও ব্লগ:

http://t-machine.org/index.php/2009/10/13/how-to-make-an-iphone-static-library-part-1/

http://blog.costan.us/2009/12/fat-iphone-static-libraries-device-and.html


8
অ্যাপল টেক নোটটি তখন থেকেই বলা হয়েছে যে "এই সমস্যাটি সমাধান করার জন্য, স্ট্যাটিক লাইব্রেরির সাথে লক্ষ্য সংযোগের লক্ষ্য-সংযোগটি অবশ্যই লিঙ্কারের সাথে -ObjC বিকল্পটি পাস করতে হবে।" যা উপরে উল্লিখিত বিপরীত। আমরা কেবল নিশ্চিত করেছি যে অ্যাপ্লিকেশনটির সাথে লিঙ্ক করার সময় আপনাকে অন্তর্ভুক্ত করতে হবে এবং লাইব্রেরি নিজেই নয়।
কেন আস্পেসলাগ

ডক বিকাশকারী.অ্যাপল. com/library/mac/#qa/qa1490/_index.html এর মতে , আমাদের -ল_লোড বা -ফোর্স_লোড পতাকা ব্যবহার করা উচিত। উল্লিখিত হিসাবে, লিঙ্কারটিতে 64 বিট ম্যাক অ্যাপ এবং আইফোন অ্যাপে বাগ রয়েছে। "গুরুত্বপূর্ণ: -৪-বিট এবং আইফোন ওএস অ্যাপ্লিকেশনগুলির জন্য, একটি লিঙ্কার বাগ রয়েছে যা কেবলমাত্র বিভাগ এবং কোনও শ্রেণিহীন স্ট্যাটিক লাইব্রেরি থেকে অবজেক্ট ফাইল লোড করা থেকে ওউজজিকে বাধা দেয় The কার্যক্রমটি -আর_লোড বা -ফোর্স_লোড পতাকা ব্যবহার করা হয়।"
রবিন

2
@ কেন এসপেলাগ: ধন্যবাদ, আমারও একই সমস্যা ছিল। -ObjC এবং-সমস্ত_লোড ফ্ল্যাগগুলি লাইব্রেরিতে নয় , অ্যাপটিতে নিজেই যুক্ত করা দরকার ।
টাইটানিয়ামডেকয়

3
দুর্দান্ত উত্তর, যদিও এই প্রশ্নের নতুনদের মনে করা উচিত এটি এখন পুরানো date Tonklon এর উত্তর দেখুন stackoverflow.com/a/9224606/322748 (all_load / force_load আর প্রয়োজন হয়)
জে Peyer

আমি প্রায় আধা ঘন্টার জন্য এই জিনিসগুলিকে আটকে রেখেছি এবং একটি পরীক্ষা এবং ত্রুটির সাথে আমি এটিকে সবেমাত্র প্রকাশ করেছি। যাইহোক ধন্যবাদ. এই উত্তরটি +1 এর মূল্য এবং আপনি পেয়েছেন !!!
দীপুকজায়ান

118

ভ্লাদিমিরের উত্তরটি আসলে বেশ ভাল, তবে আমি এখানে আরও কিছু পটভূমি জ্ঞান দিতে চাই। হতে পারে একদিন কেউ আমার উত্তর খুঁজে পেয়েছে এবং এটি সহায়ক হতে পারে।

সংকলক উত্স ফাইলগুলিকে (.c, .cc, .cpp, .m) রূপান্তর করে। প্রতি উত্স ফাইলটিতে একটি অবজেক্ট ফাইল রয়েছে। অবজেক্ট ফাইলগুলিতে প্রতীক, কোড এবং ডেটা রয়েছে। অপারেটিং সিস্টেম দ্বারা অবজেক্ট ফাইলগুলি সরাসরি ব্যবহারযোগ্য হয় না।

এখন যখন একটি ডায়নামিক লাইব্রেরি (.dlib), একটি কাঠামো, একটি লোডযোগ্য বান্ডিল (.বান্ডেল) বা এক্সিকিউটেবল বাইনারি তৈরি করা হয়, তখন এই বস্তু ফাইলগুলি লিংক দ্বারা একত্রে সংযুক্ত হয়ে অপারেটিং সিস্টেমটিকে "ব্যবহারযোগ্য" হিসাবে বিবেচনা করা এমন কিছু উত্পাদন করতে পারে, যেমন এটি কিছু করতে পারে সরাসরি একটি নির্দিষ্ট মেমরি ঠিকানায় লোড করুন।

তবে একটি স্ট্যাটিক লাইব্রেরি তৈরি করার সময়, এই সমস্ত অবজেক্ট ফাইলগুলি কেবল একটি বড় সংরক্ষণাগার ফাইলে যুক্ত করা হয়, সুতরাং স্থির লাইব্রেরির (আর্কাইভের জন্য .a) এক্সটেনশন। সুতরাং একটি .a ফাইল অবজেক্ট (.o) ফাইলগুলির সংরক্ষণাগার ছাড়া কিছুই নয়। কোনও টিআরআরচ সংরক্ষণাগার বা কোনও পীড়ন ছাড়াই একটি জিপ সংরক্ষণাগার সম্পর্কে ভাবেন। পুরো একগুচ্ছ .o ফাইলের তুলনায় একক .a ফাইলের অনুলিপি করা খুব সহজ (জাভা-এর মতো, যেখানে আপনি সহজেই বিতরণের জন্য। ক্লাস ফাইলগুলিকে একটি .jar সংরক্ষণাগারে প্যাক করেন)।

কোনও বাইনারিটিকে স্থির গ্রন্থাগারের সাথে সংযুক্ত করার সময় (= সংরক্ষণাগার) লিঙ্কারটি সংরক্ষণাগারে সমস্ত চিহ্নের একটি টেবিল পাবেন এবং পরীক্ষা করুন যে এই চিহ্নগুলির মধ্যে কোনটি বাইনারি দ্বারা রেফারেন্স করা হয়েছে। কেবলমাত্র রেফারেন্সড চিহ্ন সহ অবজেক্ট ফাইলগুলি লিঙ্কার দ্বারা লোড করা হয় এবং লিঙ্কিংয়ের প্রক্রিয়া দ্বারা বিবেচিত হয়। উদাহরণস্বরূপ, যদি আপনার সংরক্ষণাগারে 50 টি অবজেক্ট ফাইল রয়েছে তবে কেবল 20 টি বাইনারি দ্বারা ব্যবহৃত চিহ্ন রয়েছে, কেবল 20 টি লিঙ্কার দ্বারা লোড করা হয়েছে, অন্য 30 টি লিঙ্কিংয়ের প্রক্রিয়াতে সম্পূর্ণ উপেক্ষা করা হবে।

এটি সি এবং সি ++ কোডের জন্য বেশ কার্যকরভাবে কাজ করে, কারণ এই ভাষাগুলি সংকলনের সময় যতটা সম্ভব চেষ্টা করার চেষ্টা করে (যদিও সি ++ তে কিছু রানটাইম-কেবল কিছু বৈশিষ্ট্য রয়েছে)। ওবজ-সি অবশ্য আলাদা ধরণের ভাষা। ওবজে-সি রানটাইম বৈশিষ্ট্যগুলির উপর অনেক বেশি নির্ভর করে এবং অনেকগুলি ওবিজে-সি বৈশিষ্ট্যগুলি কেবলমাত্র রানটাইম-র বৈশিষ্ট্য। ওবজে-সি ক্লাসে সি সি ফাংশন বা গ্লোবাল সি ভেরিয়েবলের সাথে তুলনাযোগ্য চিহ্ন রয়েছে (কমপক্ষে বর্তমান ওজেজে-সি রানটাইমটিতে)। কোনও লিঙ্কার দেখতে পাচ্ছে যে কোনও শ্রেণি রেফারেন্স করা হয়েছে কি না, তাই এটি নির্ধারণ করতে পারে কোনও শ্রেণি ব্যবহৃত হচ্ছে কি না। আপনি যদি কোনও স্ট্যাটিক লাইব্রেরিতে কোনও অবজেক্ট ফাইল থেকে ক্লাস ব্যবহার করেন তবে এই বস্তু ফাইলটি লিঙ্কার দ্বারা লোড করা হবে কারণ লিঙ্কারটি প্রতীকটি ব্যবহৃত হচ্ছে। বিভাগগুলি কেবলমাত্র রানটাইম-এর বৈশিষ্ট্য, বিভাগগুলি ক্লাস বা ফাংশনগুলির মতো চিহ্ন নয় এবং এর অর্থ এটিও হ'ল কোনও লিঙ্কার নির্ধারণ করতে পারে না কোনও বিভাগ ব্যবহার হচ্ছে কি না।

লিঙ্কার যদি ওবজে-সি কোডযুক্ত কোনও বস্তু ফাইল লোড করে তবে এর সমস্ত ওবজ-সি অংশ সর্বদা লিঙ্কিংয়ের পর্যায়ে রয়েছে। সুতরাং যদি বিভাগগুলি যুক্ত কোনও বস্তু ফাইল লোড করা হয় কারণ এটির যে কোনও প্রতীককে "ব্যবহারে" হিসাবে বিবেচনা করা হয় (এটি একটি শ্রেণি হোন, এটি কোনও ফাংশন হোক, এটি একটি বিশ্বব্যাপী পরিবর্তনশীল), বিভাগগুলি পাশাপাশি লোড করা হয় এবং রানটাইম এ উপলব্ধ হবে । তবুও যদি অবজেক্ট ফাইলটি স্বয়ংক্রিয়ভাবে লোড না করা হয় তবে এর বিভাগগুলি রানটাইম এ উপলব্ধ হবে না। একটি বস্তু ফাইল শুধুমাত্র বিভাগ করা হয় না লোড কারণ এটা রয়েছে কোন চিহ্ন linker হবে কি কখনো "ব্যবহার করার ক্ষেত্রে 'বিবেচনা। এবং এটি এখানে পুরো সমস্যা।

বেশ কয়েকটি সমাধান প্রস্তাব করা হয়েছে এবং এখন আপনি কীভাবে জানেন যে এই সমস্ত কীভাবে একসাথে অভিনয় করা হয়, আসুন প্রস্তাবিত সমাধানটির উপর অন্য নজর দেওয়া যাক:

  1. একটি সমাধান -all_loadলিঙ্কার কলটিতে যুক্ত করা। সেই লিঙ্কার পতাকাটি আসলে কী করবে? প্রকৃতপক্ষে এটি লিঙ্কটিকে নীচে বলেছে " আপনি যদি কোনও চিহ্ন ব্যবহার বা না দেখে থাকেন তবে নির্ধারিত সমস্ত আর্কাইভের সমস্ত অবজেক্ট ফাইল লোড করুন " অবশ্যই এটি কাজ করবে; তবে এটি বরং বড় বাইনারিও তৈরি করতে পারে।

  2. আর একটি সমাধান হ'ল -force_loadআর্কাইভের পথ সহ লিংক কলটিতে যুক্ত করা। এই পতাকাটি ঠিক মতো কাজ করে -all_loadতবে কেবলমাত্র নির্দিষ্ট সংরক্ষণাগারটির জন্য। অবশ্যই এটি কাজ করবে।

  3. সর্বাধিক জনপ্রিয় সমাধানটি -ObjCলিংক কলটিতে যুক্ত করা। সেই লিঙ্কার পতাকাটি আসলে কী করবে? এই পতাকাটি লিঙ্ককারীকে " সমস্ত সংরক্ষণাগার থেকে সমস্ত অবজেক্ট ফাইলগুলি লোড করুন যদি আপনি দেখতে পান যে সেগুলিতে কোনও ওজেজে-সি কোড রয়েছে "। এবং "যে কোনও ওবজ-সি কোড" এর মধ্যে বিভাগ অন্তর্ভুক্ত রয়েছে। এটি পাশাপাশি কাজ করবে এবং এটি কোনও ওজেজে-সি কোডযুক্ত অবজেক্ট ফাইলগুলি লোড করার জন্য বাধ্য করবে না (এগুলি এখনও কেবলমাত্র চাহিদা অনুযায়ী লোড করা হয়)।

  4. আরেকটি সমাধান হ'ল নতুন এক্সকোড বিল্ড সেটিংস Perform Single-Object Prelink। এই সেটিংটি কী করবে? যদি সক্ষম করা থাকে, সমস্ত অবজেক্ট ফাইল (মনে রাখবেন, উত্স ফাইল প্রতি এক আছে) একক বস্তু ফাইলে একত্রিত হয়ে যায় (এটি আসল সংযোগ নয়, তাই নাম প্রিলিংক ) এবং এই একক অবজেক্ট ফাইল (কখনও কখনও "মাস্টার অবজেক্ট" নামেও পরিচিত ফাইল ") এর পরে সংরক্ষণাগারে যুক্ত করা হয়। এখন যদি মাস্টার অবজেক্ট ফাইলের কোনও প্রতীক ব্যবহার হিসাবে বিবেচিত হয় তবে পুরো মাস্টার অবজেক্ট ফাইলটি ব্যবহার হিসাবে বিবেচিত হয় এবং সুতরাং এর সমস্ত অবজেক্টি-সি অংশ সর্বদা লোড হয়। এবং যেহেতু ক্লাসগুলি সাধারণ প্রতীক, তাই সমস্ত বিভাগ পেতে এই জাতীয় স্ট্যাটিক লাইব্রেরি থেকে একটি ক্লাস ব্যবহার করা যথেষ্ট।

  5. চূড়ান্ত সমাধানটি হ'ল ভ্লাদিমির তার উত্তরের একেবারে শেষে যুক্ত কৌশলটি। যে কোনও উত্স ফাইলে কেবল বিভাগগুলি ঘোষণা করে একটি " জাল প্রতীক " রাখুন । আপনি রানটাইম সময়ে যে কোনও বিভাগ ব্যবহার করতে চান তা নিশ্চিত করে নিন যে আপনি কোনওভাবেই সংকলনকালে নকল প্রতীকটি উল্লেখ করেছেন , কারণ এর ফলে বস্তু ফাইলটি লিংককারী দ্বারা লোড হতে পারে এবং এইভাবে এটিতে সমস্ত ওবিজে-সি কোড রয়েছে। উদাহরণস্বরূপ এটি খালি ফাংশন বডি সহ কোনও ফাংশন হতে পারে (যা ডাকা হওয়ার সময় কিছুই করবে না) বা এটি বিশ্বব্যাপী ভেরিয়েবল অ্যাক্সেস হতে পারে (যেমন বিশ্বব্যাপীintএকবার পড়ুন বা একবার লিখিত, এটি যথেষ্ট)। উপরের অন্যান্য সমস্ত সমাধানের বিপরীতে, এই সমাধানটি রানাইল সময়ে সংকলিত কোডে কোন বিভাগগুলি উপলব্ধ তা নিয়ন্ত্রণ নিয়ন্ত্রণ করে (যদি এটি তাদের লিঙ্কযুক্ত এবং উপলব্ধ হতে চায় তবে এটি প্রতীকটি অ্যাক্সেস করে, অন্যথায় এটি প্রতীকটি অ্যাক্সেস করে না এবং লিঙ্কার উপেক্ষা করবে) এটা)।

এই সব ভাবেন।

ওহ, অপেক্ষা করুন, আরও একটি জিনিস রয়েছে:
লিঙ্কারের একটি বিকল্পের নাম রয়েছে -dead_strip। এই বিকল্পটি কী করে? যদি লিঙ্কার কোনও অবজেক্ট ফাইলটি লোড করার সিদ্ধান্ত নিয়ে থাকে তবে অবজেক্ট ফাইলের সমস্ত চিহ্নগুলি ব্যবহার করা হোক না কেন, লিঙ্কযুক্ত বাইনারিগুলির অংশ হয়ে যায়। উদাহরণস্বরূপ, কোনও অবজেক্ট ফাইলে 100 টি ফাংশন রয়েছে তবে তাদের মধ্যে কেবল একটি বাইনারি দ্বারা ব্যবহৃত হয়, সমস্ত 100 ফাংশন বাইনারিটিতে এখনও যুক্ত করা হয় কারণ বস্তু ফাইলগুলি সম্পূর্ণরূপে যুক্ত হয় বা সেগুলি মোটেই যুক্ত হয় না। আংশিকভাবে কোনও অবজেক্ট ফাইল যুক্ত করা লিংকারদের দ্বারা সমর্থিত নয়।

তবে, যদি আপনি লিঙ্কারটিকে "মৃত স্ট্রিপ" বলুন, লিঙ্কারটি প্রথমে সমস্ত বস্তুর ফাইলগুলিকে বাইনারি যুক্ত করবে, সমস্ত রেফারেন্স সমাধান করবে এবং শেষ অবধি ব্যবহার না করা প্রতীকগুলির জন্য বাইনারি স্ক্যান করবে (অথবা কেবলমাত্র অন্য চিহ্নগুলির ব্যবহারে নয়) ব্যবহার)। ব্যবহারযোগ্য না হিসাবে পাওয়া সমস্ত প্রতীকগুলি তারপরে অপ্টিমাইজেশন পর্যায়ে অংশ হিসাবে সরানো হবে। উপরের উদাহরণে, 99 অব্যবহৃত ফাংশনগুলি আবার সরানো হয়েছে। এই খুব দরকারী যদি আপনি চান অপশন ব্যবহার করেন -load_all, -force_loadবা Perform Single-Object Prelinkকারণ এই বিকল্পগুলি সহজে আপ বাইনারি মাপ নাটকীয়ভাবে কিছু ক্ষেত্রে বাজাতে পারবে এবং মৃত Stripping আবার অব্যবহৃত কোড এবং ডেটা মুছে যাবে।

ডেড স্ট্রিপিং সি কোডের জন্য খুব ভাল কাজ করে (উদাঃ যেমন অব্যবহৃত ফাংশন, ভেরিয়েবল এবং ধ্রুবকগুলি প্রত্যাশা অনুযায়ী মুছে ফেলা হয়) এবং এটি সি ++ এর জন্যও বেশ ভাল কাজ করে (যেমন অব্যবহৃত ক্লাস মুছে ফেলা হয়)। এটি নিখুঁত নয়, কিছু ক্ষেত্রে কিছু প্রতীকগুলি সরিয়ে ফেলা ঠিক না হলেও এটি মুছে ফেলা হয় না, তবে বেশিরভাগ ক্ষেত্রে এটি এই ভাষার পক্ষে বেশ ভাল কাজ করে।

ওবজ-সি সম্পর্কে কী? এটি সম্পর্কে ভুলে যাও! ওবজ-সি এর জন্য কোনও মৃত স্ট্রিপিং নেই। যেহেতু ওবজে-সি একটি রানটাইম-বৈশিষ্ট্যযুক্ত ভাষা, তাই সংকলক সংকলনের সময় বলতে পারে না যে প্রতীকটি সত্যই ব্যবহৃত হচ্ছে কিনা। উদাহরণস্বরূপ কোনও ওজজ-সি ক্লাস ব্যবহার করা হয় না যদি সরাসরি কোনও রেফারেন্সিং থাকে তবে সঠিক? ভুল! আপনি গতিতে ক্লাসের নাম সম্বলিত একটি স্ট্রিং তৈরি করতে পারেন, সেই নামের জন্য একটি শ্রেণি নির্দেশকের জন্য অনুরোধ করতে পারেন এবং গতিশীলভাবে বর্গ বরাদ্দ করতে পারেন। যেমন পরিবর্তে

MyCoolClass * mcc = [[MyCoolClass alloc] init];

আমিও লিখতে পারতাম

NSString * cname = @"CoolClass";
NSString * cnameFull = [NSString stringWithFormat:@"My%@", cname];
Class mmcClass = NSClassFromString(cnameFull);
id mmc = [[mmcClass alloc] init];

উভয় ক্ষেত্রেই mmc"মাইকুলক্লাস" শ্রেণীর কোনও জিনিসের রেফারেন্স , তবে দ্বিতীয় কোডের নমুনায় এই শ্রেণীর সরাসরি কোনও রেফারেন্স পাওয়া যায় না (এমনকি স্ট্যাটিক স্ট্রিং হিসাবে শ্রেণীর নামও নয়)। সবকিছু কেবল রানটাইমের সময় ঘটে। এবং যে যদিও ক্লাস এর দ্বারা আসলে বাস্তব প্রতীক। বিভাগগুলির জন্য এটি আরও খারাপ, কারণ এগুলি এমনকি প্রকৃত প্রতীক নয়।

সুতরাং আপনার যদি কয়েক শতাধিক অবজেক্টের সাথে স্ট্যাটিক লাইব্রেরি থাকে তবে আপনার বেশিরভাগ বাইনারিগুলির মধ্যে কেবল কয়েকটিগুলির প্রয়োজন হয় তবে আপনি উপরের সমাধানগুলি (1) থেকে (4) ব্যবহার না করা পছন্দ করতে পারেন। অন্যথায় আপনি এই সমস্ত শ্রেণীর সমন্বিত খুব বড় বাইনারি দিয়ে শেষ করেন, যদিও তাদের অধিকাংশই ব্যবহৃত হয় না। ক্লাসগুলির জন্য আপনার সাধারণত কোনও বিশেষ সমাধানের প্রয়োজন হয় না কারণ ক্লাসগুলির আসল প্রতীক থাকে এবং যতক্ষণ আপনি এগুলি সরাসরি উল্লেখ করেন (দ্বিতীয় কোডের নমুনায় নয়), লিঙ্কারটি নিজের ব্যবহারটি খুব ভালভাবে চিহ্নিত করবে। বিভাগগুলির জন্য, তবে সমাধান (5) বিবেচনা করুন, কারণ এটি কেবল আপনার সত্যিকারের বিভাগগুলি অন্তর্ভুক্ত করা সম্ভব করে তোলে।

উদাহরণস্বরূপ, আপনি যদি এনএসডিটার জন্য কোনও বিভাগ চান, উদাহরণস্বরূপ এটিতে একটি সংক্ষেপণ / ডিকম্প্রেশন পদ্ধতি যুক্ত করে আপনি একটি শিরোনাম ফাইল তৈরি করতে চান:

// NSData+Compress.h
@interface NSData (Compression)
    - (NSData *)compressedData;
    - (NSData *)decompressedData;
@end

void import_NSData_Compression ( );

এবং একটি বাস্তবায়ন ফাইল

// NSData+Compress
@implementation NSData (Compression)
    - (NSData *)compressedData 
    {
        // ... magic ...
    }

    - (NSData *)decompressedData
    {
        // ... magic ...
    }
@end

void import_NSData_Compression ( ) { }

এখনই নিশ্চিত হয়ে নিন যে আপনার কোডের যে কোনও জায়গায় import_NSData_Compression()বলা হয়েছে। এটি কোথায় ডাকা হয় বা কতবার বলা হয় তা বিবেচনা করে না। আসলে এটি আসলেই মোটেও ডাকতে হবে না, লিঙ্কার যদি তাই মনে করে তবে এটি যথেষ্ট। যেমন আপনি নীচের কোডটি আপনার প্রকল্পের যে কোনও জায়গায় রাখতে পারেন:

__attribute__((used)) static void importCategories ()
{
    import_NSData_Compression();
    // add more import calls here
}

আপনাকে আপনার importCategories()কোডটিতে কখনও কল করতে হবে না, বৈশিষ্ট্যটি সংকলক এবং লিঙ্কারকে বিশ্বাস করে যে এটি বলা হয়েছিল, এমনকি এটি না থাকলেও।

এবং একটি চূড়ান্ত টিপ:
আপনি যদি -whyloadচূড়ান্ত লিঙ্ক কলটিতে যোগ করেন তবে লিঙ্কারটি বিল্ড লগে মুদ্রণ করবে যা কোন লাইব্রেরি থেকে কোন বস্তুটি এটি ব্যবহার করবে তা কোন চিহ্নের ব্যবহারের কারণে লোড হয়েছে। এটি কেবল ব্যবহৃত হিসাবে বিবেচিত প্রথম প্রতীকটি মুদ্রণ করবে, তবে এটি অবশ্যই অবজেক্ট ফাইলটির ব্যবহারের একমাত্র প্রতীক নয়।


1
উল্লেখ -whyloadকরার জন্য আপনাকে ধন্যবাদ , লিঙ্কার কেন কিছু করছে তা ডিবাগ করার চেষ্টা করা বেশ কঠিন হতে পারে!
বেন এস

একটি বিকল্প Dead Code Strippingআছে Build Settings>Linking। এটি কি -dead_stripযোগ হিসাবে একই Other Linker Flags?
জিয়াও

1
@ শীন হ্যাঁ, এটি একই রকম। প্রতিটি বিল্ড সেটিংয়ের জন্য বিদ্যমান "কুইক হেল্প" কেবলমাত্র পড়ুন, উত্তরটি ঠিক আছে: postimg.org/image/n7megftnr/full
মক্কি

@ মেক্কি ধন্যবাদ আমি পরিত্রাণ পেতে চেষ্টা করেছি -ObjC, তাই আমি আপনার হ্যাক চেষ্টা করেছিলাম কিন্তু এটি অভিযোগ করে "import_NSString_jsonObject()", referenced from: importCategories() in main.o ld: symbol(s) not found। আমি import_NSString_jsonObjectআমার এমবেডড ফ্রেমওয়ার্কটি নাম রেখেছি এবং আমার শেষের দিকে বিবৃতি দিয়ে Utilityযুক্ত করেছি । #import <Utility/Utility.h>__attribute__AppDelegate.h
জিয়াও

@ সিয়ান যদি লিঙ্কারটি প্রতীকটি খুঁজে না পায়, আপনি স্ট্যাটিক লাইব্রেরির সাথে সংযোগ দিচ্ছেন না যেখানে প্রতীক রয়েছে। একটি ফ্রেমওয়ার্ক থেকে কেবল আহ ফাইলটি আমদানি করা ফ্রেমওয়ার্কের বিপরীতে এক্সকোড লিঙ্ক তৈরি করবে না। ফ্রেমওয়ার্কগুলি বিল্ড ফেজের সাথে লিঙ্কটিতে অবশ্যই ফ্রেমওয়ার্কটি স্পষ্টভাবে লিঙ্ক করা উচিত। আপনি নিজের লিঙ্কিং ইস্যুটির জন্য একটি নিজস্ব প্রশ্ন খুলতে চাইতে পারেন, মন্তব্যে উত্তর দেওয়া জটিল and
মক্কি 13'15

24

এই সমস্যাটি এলএলভিএম-এ স্থির করা হয়েছে । এলএলভিএম ২.৯ এর অংশ হিসাবে ফিক্স শিপস হ'ল প্রথম এক্সকোড সংস্করণটি সংশোধন করে এলএলভিএম ৩.০ সহ এক্সকোড ৪.২ শিপিং। এক্সকোড ৪.২ এর সাথে কাজ করার সময় এর ব্যবহার -all_loadবা -force_loadআর প্রয়োজন -ObjC হয় না still


আপনি যদি এই বিষয়ে নিশ্চিত? আমি এলসিভিএম ৩.১ এর সংকলন করে, এক্সকোড ৪.৩.২ ব্যবহার করে একটি আইওএস প্রকল্পে কাজ করছি এবং এটি এখনও আমার জন্য একটি সমস্যা ছিল।
অ্যাশলে মিলস

ঠিক আছে, এটি একটি সামান্য ভুল ছিল। -ObjCপতাকা এখনও প্রয়োজন এবং সবসময় হতে হবে। কর্মক্ষেত্রটি ছিল -all_loadবা এর ব্যবহার -force_load। আর তার আর দরকার নেই। আমি উপরে আমার উত্তর স্থির করেছি।
টনক্লন

-ল_লোড পতাকা (এটি অপ্রয়োজনীয় হলেও) অন্তর্ভুক্ত করার কোনও অসুবিধা আছে কি? এটি কি কোনও উপায়ে সংকলন / প্রবর্তনের সময়কে প্রভাবিত করে?
জেডএস

আমি এক্সকোড সংস্করণ 4.5 (4G182) এর সাথে কাজ করছি এবং -অবজিসি পতাকাটি আমার অপরিচিত সনাক্তকারী ত্রুটিটিকে তৃতীয় পক্ষের নির্ভরতা থেকে সরানো হয়েছে যা আমি উদ্দেশ্য সি রানটাইমের গভীরতার মতো দেখতে ব্যবহার করতে চাইছি: "- [__ এনএসআরমিমে্যাপ :]: অচেনা নির্বাচক উদাহরণ হিসাবে প্রেরণ করা হয়েছে ... "। কোন সংকেত সনাক্ত করুন?
রবার্ট অ্যাটকিনস

16

আপনার স্ট্যাটিক লাইব্রেরিটি সংকলন করার সময় এই সমস্যাটি সম্পূর্ণরূপে সমাধান করার জন্য আপনাকে যা করতে হবে তা এখানে:

হয় এক্সকোড বিল্ড সেটিংসে যান এবং একক-অবজেক্ট প্রিলিঙ্কটি ইয়েসে বা GENERATE_MASTER_OBJECT_FILE = YESআপনার বিল্ড কনফিগারেশন ফাইলটিতে সেট করুন ।

ডিফল্টরূপে, লিঙ্কার প্রতিটি .m ফাইলের জন্য একটি .o ফাইল উত্পন্ন করে। সুতরাং বিভাগগুলি বিভিন্ন .o ফাইলগুলি পায়। লিঙ্কার যখন একটি স্ট্যাটিক লাইব্রেরি .o ফাইলগুলির দিকে তাকাবে, তখন এটি প্রতি ক্লাসে সমস্ত চিহ্নের একটি সূচক তৈরি করে না (রানটাইম উইল, কোন ব্যাপার না)।

এই নির্দেশিকাটি লিঙ্কারকে সমস্ত বস্তুকে একত্রে একটি বড় .o ফাইলে প্যাক করতে বলবে এবং এর মাধ্যমে এটি লিঙ্কারকে স্ট্যাটিক লাইব্রেরি প্রক্রিয়াকরণের জন্য সমস্ত শ্রেণির বিভাগ সূচক পেতে বাধ্য করে।

আশা করি এটি স্পষ্ট করে দেয়।


এটি লিঙ্কিং টার্গেটে -ObjC যুক্ত না করে আমার জন্য এটি স্থির করে।
ম্যাথু ক্রেনশো

ব্লকসকিট লাইব্রেরির সর্বশেষতম সংস্করণে আপডেট করার পরে , সমস্যাটি সমাধান করার জন্য আমাকে এই সেটিংটি ব্যবহার করতে হয়েছিল (আমি ইতিমধ্যে -ObjC পতাকা ব্যবহার করছি তবে এখনও সমস্যাটি দেখছি)।
রাকমোহ

1
আসলে আপনার উত্তরটি একদম ঠিক নয়। আমি "লিঙ্কারকে একই শ্রেণীর সমস্ত বিভাগকে এক .o ফাইলের সাথে একত্রে প্যাক করতে বলি না", এটি লিঙ্কারকে স্ট্যাটিক লাইব্রেরি তৈরির আগে সমস্ত অবজেক্ট ফাইল (.o) কে একটি একক, বড় অবজেক্ট ফাইলে লিঙ্ক করতে বলবে " তাদের / এটি। কোনও প্রতীক লাইব্রেরি থেকে উল্লেখ করা হলে, সমস্ত প্রতীক লোড করা হয়। তবে, কোনও চিহ্নকে উল্লেখ না করা হলে এটি কাজ করবে না (উদাহরণস্বরূপ যদি গ্রন্থাগারে কেবল বিভাগগুলি থাকে তবে এটি কাজ করবে না)।
মক্কি

আমি মনে করি না যে আপনি এনএসডাটার মতো বিদ্যমান ক্লাসে বিভাগ যুক্ত করলে এটি কাজ করবে।
বব হোয়াইটম্যান

আমারও বিদ্যমান ক্লাসে বিভাগ যুক্ত করতে সমস্যা হচ্ছে। আমার প্লাগইন রান সময়ে তাদের চিনতে পারে না।
ডেভিড ডানহাম

9

স্থির গ্রন্থাগার লিঙ্কিংয়ের আলোচনার আলোচনার সাথে সাথেই একটি বিষয় উল্লেখ করা হয় যা হ'ল আপনার নিজের বিল্ড পর্যায়গুলিতে বিভাগগুলি> কপি ফাইল এবং স্ট্যাটিক লাইব্রেরির উত্সগুলি সংকলন করতে হবে

অ্যাপল আইওএস- এ তাদের সম্প্রতি প্রকাশিত স্ট্যাটিক লাইব্রেরি ব্যবহার করেও এই সত্যটির উপর জোর দেয় না ।

আমি একটি পুরো দিন অতিবাহিত -objC এবং -all_load ইত্যাদি বৈচিত্র সমস্ত প্রকারের চেষ্টা .. কিন্তু কিছুই এটা বেরিয়ে আসেন .. এই প্রশ্ন আমার মনোযোগ যে সমস্যা নিয়ে আসে। (আমাকে ভুল করবেন না .. তবুও আপনাকে -objC স্টাফ করতে হবে .. তবে এটি কেবল এটির চেয়ে বেশি)।

এছাড়াও আরও একটি ক্রিয়া যা আমাকে সর্বদা সহায়তা করে তা হ'ল আমি সর্বদা অন্তর্ভুক্ত স্ট্যাটিক লাইব্রেরিটি প্রথমে নিজেই তৈরি করি .. তারপরে আমি ঘের প্রয়োগটি তৈরি করি ..


-1

আপনার সম্ভবত স্ট্যাটিক লাইব্রেরির "পাবলিক" শিরোনামে বিভাগটি থাকা দরকার: # মিম্পোর্ট "মাইস্ট্যাটিক লাইব.h"

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.