কোনও এনএসএরে সি-স্ট্রাক্ট রাখার সর্বোত্তম উপায় কী?


89

একটিতে সি-কাঠামো সংরক্ষণ করার স্বাভাবিক উপায় কী NSArray? সুবিধা, অসুবিধাগুলি, স্মৃতি সামলানো?

উল্লেখযোগ্যভাবে, নীচে জাস্টিন এবং ক্যাটফিশ দ্বারা উত্থাপিত valueWithBytesএবং valueWithPointer- এর মধ্যে পার্থক্য কী ।

valueWithBytes:objCType:ভবিষ্যতের পাঠকদের জন্য অ্যাপলের আলোচনার একটি লিঙ্ক এখানে ...

কিছু ঘুরপথে সমাধানের চিন্তা এবং আরো কর্মক্ষমতা দিকে তাকিয়ে জন্য, Evgen ব্যবহার ইস্যু তুলেছে STL::vectorমধ্যে সি ++

(এটি একটি আকর্ষণীয় বিষয় উত্থাপন করে: একটি দ্রুত সি লাইব্রেরি কি অসদৃশ নয় STL::vectorতবে অনেক বেশি হালকা, এটি ন্যূনতম "অ্যারেগুলির পরিপাটি পরিচালনা" এর জন্য অনুমতি দেয় ...?)

সুতরাং আসল প্রশ্ন ...

উদাহরণ স্বরূপ:

typedef struct _Megapoint {
    float   w,x,y,z;
} Megapoint;

সুতরাং: নিজের মতো করে কাঠামোটি সংরক্ষণ করার মতো সাধারণ, সর্বোত্তম, মূর্তিমান পদ্ধতি কী NSArrayএবং আপনি কীভাবে সেই মূর্তিটিতে মেমরি পরিচালনা করবেন?

দয়া করে নোট করুন যে আমি বিশেষভাবে স্ট্রাক্ট সঞ্চয় করার জন্য সাধারণ প্রতিমাটির সন্ধান করছি। অবশ্যই, কেউ একটি নতুন ছোট ক্লাস তৈরি করে বিষয়টি এড়াতে পারে। যাইহোক আমি জানতে চাই যে কীভাবে একটি সাধারণ অ্যারেতে স্ট্রাক্ট রাখার জন্য সাধারণ প্রতিমাটি, ধন্যবাদ।

বিটিডব্লিউ এখানে এনএসডিটা অ্যাপ্রোচ যা সম্ভবত? সেরা না ...

Megapoint p;
NSArray *a = [NSArray arrayWithObjects:
    [NSData dataWithBytes:&p length:sizeof(Megapoint)],
    [NSData dataWithBytes:&p length:sizeof(Megapoint)],
    [NSData dataWithBytes:&p length:sizeof(Megapoint)],
        nil];

রেফারেন্সের পয়েন্ট হিসাবে বিটিডাব্লু এবং জারেট হার্ডিকে ধন্যবাদ, এখানে কীভাবে সংরক্ষণ করতে হবে CGPointsএবং কীভাবে মিলবে তা এখানে NSArray:

NSArray *points = [NSArray arrayWithObjects:
        [NSValue valueWithCGPoint:CGPointMake(6.9, 6.9)],
        [NSValue valueWithCGPoint:CGPointMake(6.9, 6.9)],
        nil];

(দেখুন কীভাবে আমি এনজিআরাইতে সহজ উপায়ে সিজিপিউইন্ট অবজেক্ট যুক্ত করতে পারি? )


এটিকে এনএসডাটাতে রূপান্তর করার জন্য আপনার কোডটি ভাল হওয়া উচিত ... এবং কোনও মেমরি ফাঁস ছাড়াই .... তবে, কেউ স্ট্রাক্টগুলির একটি স্ট্যান্ডার্ড সি ++ অ্যারে ব্যবহার করতে পারে মেগাপিয়েন্ট পি [3];
স্বপ্নিল লুকতুকে

প্রশ্নটি দু'দিন পুরানো না হওয়া পর্যন্ত আপনি অনুগ্রহ যোগ করতে পারবেন না।
ম্যাথু ফ্রেডরিক

4
ওএসএক্সের জন্য যদিও মান উইথসিজিপয়েন্ট পাওয়া যায় না। এটি ইউআইকিটির অংশ
lppier

@ আইপিয়র মান উইথপয়েন্টটি ওএস এক্স
শ্যাপাইনকোডার

উত্তর:


160

এনএসভ্যালু কেবল কোরগ্রাফিক্স স্ট্রাকচার সমর্থন করে না - আপনি এটি নিজের জন্যও ব্যবহার করতে পারেন। আমি এটি করার পরামর্শ দেব, কারণ ক্লাসটি সম্ভবত NSDataসাধারণ ডেটা কাঠামোর চেয়ে হালকা ওজন ।

কেবল নীচের মত একটি অভিব্যক্তি ব্যবহার করুন:

[NSValue valueWithBytes:&p objCType:@encode(Megapoint)];

এবং মানটি ফিরে পেতে:

Megapoint p;
[value getValue:&p];

4
@ জো ব্লো @ ক্যাটফিশ_মান এটি আসলে কাঠামোটি অনুলিপি করে p, এটির কোনও পয়েন্টার নয়। এই @encodeনির্দেশিকাটি কাঠামোর পরিমাণ কত বড় সে সম্পর্কে প্রয়োজনীয় সমস্ত তথ্য সরবরাহ করে। আপনি যখন প্রকাশ করবেন NSValue(বা অ্যারেটি করবেন) তখন এর কাঠামোর অনুলিপিটি নষ্ট হয়ে যায়। আপনি যদি getValue:ইতিমধ্যে ব্যবহার করেন তবে আপনি ভাল আছেন। "সংখ্যা এবং মান প্রোগ্রামিং টপিকস" এর "মানগুলি ব্যবহার করে" বিভাগটি দেখুন: বিকাশকারী
অ্যাপ্লিকেশন / লাইব্রেরি / আইস / ডকুমেন্টেশন / কোকোয়া / কনসেপ্টুয়াল/…

4
@ জো ব্লো বেশিরভাগ ক্ষেত্রেই সঠিক, এটি রানটাইমে পরিবর্তন করতে সক্ষম হবে না except আপনি একটি সি টাইপ নির্দিষ্ট করছেন, যা সর্বদা সম্পূর্ণরূপে জানা উচিত। যদি এটি আরও ডেটা উল্লেখ করে "বৃহত্তর" পেতে পারে, তবে আপনি সম্ভবত এটি একটি পয়েন্টারের সাহায্যে বাস্তবায়ন করতে পারবেন এবং সেই পয়েন্টারের @encodeসাহায্যে কাঠামোটি বর্ণনা করবে, তবে পয়েন্ট-টু ডেটা সম্পূর্ণরূপে বর্ণনা করবে না , যা সত্যই পরিবর্তন হতে পারে।
জাস্টিন স্পাহার-গ্রীষ্মকাল

4
হবে NSValueযখন এটি deallocated হয় স্বয়ংক্রিয়ভাবে struct হয় স্মৃতির মুক্ত? ডকুমেন্টেশন এ সম্পর্কে কিছুটা অস্পষ্ট।
ডিভাইস 1

4
সুতরাং কেবল পুরোপুরি পরিষ্কার হওয়ার জন্য, এটি NSValueনিজের মধ্যে অনুলিপি করা ডেটার মালিকানাধীন এবং আমি এটিকে মুক্ত করার বিষয়ে চিন্তা করতে হবে না (এআরসি এর আওতায়)?
ডিভিওস 1

4
@ দেভিওস সঠিক NSValueসত্যিকার অর্থে কোনও "মেমরি ম্যানেজমেন্ট" করে না — আপনি এটি অভ্যন্তরীণভাবে কাঠামোর মানটির একটি অনুলিপি হিসাবে ভাবতে পারেন। কাঠামোটিতে যদি নেস্টেড পয়েন্টার থাকে, উদাহরণস্বরূপ, NSValueফ্রি বা অনুলিপি করতে বা তাদের সাথে কিছু করা শিখতে না পারে - তবে এগুলি ঠিকানাটি অনুলিপি করে অনুলিপি করে রাখবে।
জাস্টিন স্পাহার-সামারস

7

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

CFArrayRef(এবং এর রূপান্তরকারী পাল্টা CFMutableArrayRef) কোনও অ্যারে অবজেক্ট তৈরি করার সময় বিকাশকারীকে আরও নমনীয়তা সহ্য করে। মনোনীত প্রাথমিকের চতুর্থ যুক্তি দেখুন:

CFArrayRef CFArrayCreate (
    CFAllocatorRef allocator,
    const void **values,
    CFIndex numValues,
    const CFArrayCallBacks *callBacks
);

এটি আপনাকে অনুরোধ করতে অনুমতি দেয় যে CFArrayRefঅবজেক্টটি কোর ফাউন্ডেশনের মেমরি ম্যানেজমেন্ট রুটিনগুলি ব্যবহার করবে, কোনওটি নয় এমনকি আপনার নিজের মেমরি পরিচালনার রুটিন।

বাধ্যতামূলক উদাহরণ:

// One would pass &kCFTypeArrayCallBacks (in lieu of NULL) if using CF types.
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
NSMutableArray *array = (NSMutableArray *)arrayRef;

struct {int member;} myStruct = {.member = 42};
// Casting to "id" to avoid compiler warning
[array addObject:(id)&myStruct];

// Hurray!
struct {int member;} *mySameStruct = [array objectAtIndex:0];

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

আমি এই সমাধানটি সুপারিশ করব না, তবে এটি অন্য কারও পক্ষে আগ্রহী হলে এটিকে এখানে রাখব। :-)


গাদাতে বরাদ্দ করা হিসাবে আপনার কাঠামোটি ব্যবহার করা (স্ট্যাকের পরিবর্তে) এখানে প্রদর্শিত হচ্ছে:

typedef struct {
    float w, x, y, z;
} Megapoint;

// One would pass &kCFTypeArrayCallBacks (in lieu of NULL) if using CF types.
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
NSMutableArray *array = (NSMutableArray *)arrayRef;

Megapoint *myPoint = malloc(sizeof(Megapoint);
myPoint->w = 42.0f;
// set ivars as desired..

// Casting to "id" to avoid compiler warning
[array addObject:(id)myPoint];

// Hurray!
Megapoint *mySamePoint = [array objectAtIndex:0];

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

@ জো ব্লো: এটি মেমরি ম্যানেজমেন্ট সম্পর্কিত একটি দুর্দান্ত বিষয়। আপনি ঠিকই বিভ্রান্ত হবেন: ফাংশনের স্ট্যাকটি ওভাররাইট করা হবে তার উপর নির্ভর করে আমি উপরে যে কোড নমুনা পোস্ট করেছি তা রহস্যজনক ক্রাশ হতে পারে। আমি কীভাবে আমার সমাধানটি ব্যবহার করতে পারি সে সম্পর্কে বিশদ বিবরণ দেওয়া শুরু করেছিলাম তবে বুঝতে পেরেছিলাম যে আমি উদ্দেশ্য-সি এর নিজস্ব রেফারেন্স-গণনা পুনরায় বাস্তবায়ন করছি। কমপ্যাক্ট কোডটির জন্য আমার ক্ষমা প্রার্থনা - এটি প্রবণতা নয়, অলসতার বিষয়। কোড লেখার কোনও অর্থ নেই যা অন্যরা পড়তে পারে না। :)
Sedate Alien

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

4

সি স্ট্রাক্ট যুক্ত করার অনুরূপ পদ্ধতি হ'ল পয়েন্টারটি সংরক্ষণ করা এবং পয়েন্টারটিকে ডি-রেফারেন্স হিসাবে;

typedef struct BSTNode
{
    int data;
    struct BSTNode *leftNode;
    struct BSTNode *rightNode;
}BSTNode;

BSTNode *rootNode;

//declaring a NSMutableArray
@property(nonatomic)NSMutableArray *queues;

//storing the pointer in the array
[self.queues addObject:[NSValue value:&rootNode withObjCType:@encode(BSTNode*)]];

//getting the value
BSTNode *frontNode =[[self.queues objectAtIndex:0] pointerValue];

3

যদি তুমি অনুভূতি nerdy, অথবা সত্যিই ক্লাস অনেক তৈরি করতে হবে: মাঝে মাঝে দরকারী পরিবর্তনশীল একটি objc বর্গ গঠন করা (সুত্র: class_addIvar)। এইভাবে, আপনি স্বেচ্ছাচারী ধরণের থেকে স্বেচ্ছাসেবক অবজেক্ট ক্লাস তৈরি করতে পারেন। আপনি ক্ষেত্রের দ্বারা ক্ষেত্র নির্দিষ্ট করতে পারেন, বা কেবল স্ট্রাক্টের তথ্যটি পাস করুন (তবে এটি কার্যত এনএসডিটা প্রতিরূপায়ন করছে)। কখনও কখনও দরকারী, তবে সম্ভবত বেশিরভাগ পাঠকদের জন্য একটি 'মজাদার ঘটনা'।

আমি এখানে এটি কীভাবে প্রয়োগ করব?

আপনি Class_addIvar কল করতে পারেন এবং একটি নতুন ক্লাসে একটি মেগাপিয়েন্ট ইন্সটেন্স ভেরিয়েবল যুক্ত করতে পারেন, বা আপনি রানটাইমে মেগাপিয়েন্ট ক্লাসের একটি অবজেক্ট ভেরিয়েন্ট সংশ্লেষ করতে পারেন (যেমন, মেগাপিয়েন্টের প্রতিটি ক্ষেত্রের জন্য উদাহরণ ভেরিয়েবল)।

পূর্ববর্তীটি সংকলিত অবজক শ্রেণীর সমতুল্য:

@interface MONMegapoint { Megapoint megapoint; } @end

দ্বিতীয়টি সংকলিত অবজক শ্রেণীর সমতুল্য:

@interface MONMegapoint { float w,x,y,z; } @end

আপনি আইভারগুলি যুক্ত করার পরে, আপনি পদ্ধতিগুলি সংযোজন / সংশ্লেষ করতে পারেন।

প্রাপ্তির শেষে সঞ্চিত মানগুলি পড়তে, আপনার সংশ্লেষিত পদ্ধতিগুলি ব্যবহার করুন object_getInstanceVariable, বা valueForKey:(যা প্রায়শই এই স্কেলার উদাহরণ ভেরিয়েবলগুলিকে NSNumber বা NSValue উপস্থাপনায় রূপান্তরিত করে)।

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

তদুপরি, এনএসআরাই হ'ল পয়েন্টার আকারের (বা আরও ছোট) ধরণের জন্য একটি সাধারণ পুনরায় ব্যবহারযোগ্য অ্যারে ইন্টারফেস, তবে এমন অন্যান্য পাত্রে রয়েছে যা বিভিন্ন কারণে সি-স্ট্রাক্টের জন্য আরও উপযুক্ত suited


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

(চালিয়ে যাওয়া) যদি আপনি কেবল নতুন সংগ্রহের ধরণটি এড়াতে এই সমস্ত ঝামেলাটি অতিক্রম করে থাকেন - তবে আপনার নতুন সংগ্রহের ধরণটি শিখতে হবে =) std::vector(উদাহরণস্বরূপ) সি / সি ++ প্রকার, স্ট্রাক্ট এবং ক্লাসগুলি তুলনায় আরও উপযুক্ত is এনএসআরএ। এনএসভ্যালু, এনএসডাটা বা এনএসডি অভিধানের একটি এনএসআরাই ব্যবহার করে, আপনি এক টন বরাদ্দ এবং রানটাইম ওভারহেড যুক্ত করার সময় প্রচুর পরিমাণ-সুরক্ষা হারাচ্ছেন। আপনি যদি সিটির সাথে লেগে থাকতে চান, তবে তারা সাধারণত স্ট্যাকের মধ্যে ম্যালোক এবং / অথবা অ্যারে ব্যবহার করতেন ... তবে std::vectorবেশিরভাগ জটিলতাগুলি আপনার কাছ থেকে আড়াল করে।
জাস্টিন

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

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

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

3

আপনি যদি একাধিক আবীস / আর্কিটেকচার জুড়ে এই ডেটাটি ভাগ করে থাকেন তবে দরিদ্র লোকটির আবজিক সিরিয়াল ব্যবহার করা ভাল:

Megapoint mpt = /* ... */;
NSMutableDictionary * d = [NSMutableDictionary new];
assert(d);

/* optional, for your runtime/deserialization sanity-checks */
[d setValue:@"Megapoint" forKey:@"Type-Identifier"];

[d setValue:[NSNumber numberWithFloat:mpt.w] forKey:@"w"];
[d setValue:[NSNumber numberWithFloat:mpt.x] forKey:@"x"];
[d setValue:[NSNumber numberWithFloat:mpt.y] forKey:@"y"];
[d setValue:[NSNumber numberWithFloat:mpt.z] forKey:@"z"];

NSArray *a = [NSArray arrayWithObject:d];
[d release], d = 0;
/* ... */

... বিশেষত যদি কাঠামো সময়ের সাথে সাথে পরিবর্তন করতে পারে (বা লক্ষ্যযুক্ত প্ল্যাটফর্মের সাহায্যে)। এটি অন্যান্য বিকল্পগুলির মতো দ্রুত নয়, তবে কিছু শর্তে এটি ভেঙে যাওয়ার সম্ভাবনা কম (যা আপনি গুরুত্বপূর্ণ হিসাবে নির্দিষ্ট করেছেন বা না)।

যদি সিরিয়ালযুক্ত প্রতিনিধিত্ব প্রক্রিয়াটি থেকে প্রস্থান না করে, তবে আকার / ক্রম / স্বেচ্ছাসেবী স্ট্রাইকগুলির প্রান্তিককরণ পরিবর্তন করা উচিত নয় এবং এমন বিকল্প রয়েছে যা সহজ এবং দ্রুত।

যে কোনও ইভেন্টে, আপনি ইতিমধ্যে একটি রেফ-গণনা করা অবজেক্ট যুক্ত করছেন (এনএসডাটা, এনএসওয়ালুয়ের তুলনায়) সুতরাং ... একটি মেজাপুইন্টকে ধারণ করে এমন একটি অবজেক্ট ক্লাস তৈরি করা অনেক ক্ষেত্রে সঠিক উত্তর।


@ জো ব্লো এমন কিছু যা সিরিয়ালাইজেশন করে। রেফারেন্সের জন্য: en.wikipedia.org/wiki/Serialization , parashift.com/c++-faq-lite/serialization.html , সেইসাথে অ্যাপল এর "আর্কাইভস এন্ড Serializations গাইড প্রোগ্রামিং"।
জাস্টিন

এক্সএমএল ফাইলটি সঠিকভাবে কোনও কিছু উপস্থাপন করে ধরে নেওয়া, তবে হ্যাঁ - এটি মানব-পঠনযোগ্য সিরিয়ালাইজেশনের একটি সাধারণ ফর্ম।
জাস্টিন

0

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

যদি এটি আপনার পক্ষে না হয় - এনএসভ্যালু সম্পর্কে ছেলেদের কাছ থেকে ভাল উত্তর রয়েছে - আমি মনে করি এটি সবচেয়ে গ্রহণযোগ্য।


এসটিএল একটি পাঠাগার যা আংশিকভাবে সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত। en.wikipedia.org/wiki/Standard_Template_Library cplusplus.com/reference/stl/vector
Evgen Bodunov

এটি একটি আকর্ষণীয় দাবি। এসটিএল পাত্রে বনাম কোকো ধারক শ্রেণীর গতি সুবিধা সম্পর্কে আপনার কোনও নিবন্ধের লিঙ্ক আছে?
শেডেট এলিয়েন

এখানে এনএসসিএফেরে বনাম স্টাডি :: ভেক্টর সম্পর্কে একটি আকর্ষণীয় পঠন করা হয়েছে: আপনার পোস্টে উদাহরণস্বরূপ উপহাসের উপহাস: হাস্যকর ফিশ.com/blog/archives/2005/12/23/array , সবচেয়ে বড় ক্ষতি হচ্ছে (সাধারণত) উপাদান অনুসারে একটি অবজেক্ট অবজেক্টের প্রতিনিধিত্ব করা (উদাঃ) , এনএসভ্যালু, এনএসডাটা, বা মেগাপিয়েন্ট সমন্বিত ওবজেসি টাইপের জন্য একটি বরাদ্দ এবং রেফ-গণনা করা সিস্টেমে সন্নিবেশ প্রয়োজন)। আপনি স্পষ্টতই সিএফআরয়েতে মেগাপয়েন্টকে স্টোরেজ করার জন্য সেদেট এলিয়েনের পদ্ধতিকে ব্যবহার করে তা এড়াতে পারতেন যা স্বতন্ত্র বরাদ্দ হওয়া মেগাপয়েন্টগুলির পৃথক ব্যাকিং স্টোর ব্যবহার করে (যদিও উদাহরণের মধ্যে এই পদ্ধতির চিত্রিত হয় না)। (চলমান)
জাস্টিন

তবে তারপরে এনএসসিএফএর বনাম ভেক্টর (বা অন্যান্য স্টাইল টাইপ) ব্যবহার করে গতিশীল প্রেরণের জন্য অতিরিক্ত ওভারহেড লাগবে, অতিরিক্ত ফাংশন কলগুলি যা অন্তর্ভুক্ত নয়, এক টন ধরণের সুরক্ষা এবং অপ্টিমাইজারটিতে লাথি মারার অনেক সম্ভাবনা রয়েছে ... নিবন্ধটি কেবল সন্নিবেশ করা, পড়তে, হাঁটা, মোছার দিকে দৃষ্টি নিবদ্ধ করে। সম্ভাবনাগুলি Megapoint pt[8];হ'ল , আপনি 16 বাইট সারিবদ্ধ সি-অ্যারের চেয়ে দ্রুত আর পাবেন না - এটি সি ++ এর একটি বিকল্প এবং std::arrayবিশেষত সি ++ পাত্রে (উদাহরণস্বরূপ ) - এছাড়াও উল্লেখ করুন যে উদাহরণটি বিশেষ প্রান্তিককরণ যুক্ত করে না (16 বাইট বেছে নেওয়া হয়েছিল কারণ এটি মেগাপয়েন্টের আকার)। (চলমান)
জাস্টিন

std::vectorএতে একটি সামান্য পরিমাণে ওভারহেড যুক্ত হবে এবং একটি বরাদ্দ (যদি আপনার প্রয়োজনীয় আকারটি জানেন তবে) ... তবে এটি 99.9% এরও বেশি মামলার প্রয়োজনের চেয়ে ধাতবটির আরও নিকটতম। সাধারণত, আকার ঠিক না করা বা যুক্তিসঙ্গত সর্বাধিক পরিমাণ না থাকলে আপনি কেবল একটি ভেক্টর ব্যবহার করবেন।
জাস্টিন

0

কোনও এনএসআরিতে সি স্ট্রাক্ট রাখার চেষ্টা করার পরিবর্তে আপনি এগুলি স্ট্রাক্টের অ্যারে হিসাবে একটি এনএসডিটা বা এনএসউটেবাল ডেটাতে রাখতে পারেন। এগুলি অ্যাক্সেস করার জন্য আপনি যা করবেন তা করবেন

const struct MyStruct    * theStruct = (const struct MyStruct*)[myData bytes];
int                      value = theStruct[2].integerNumber;

বা তারপর সেট করতে

struct MyStruct    * theStruct = (struct MyStruct*)[myData mutableBytes];
theStruct[2].integerNumber = 10;

0

একটি এনএসভ্যালু ব্যবহার করে ওবজে-সি অবজেক্ট হিসাবে স্ট্রাক্ট সংরক্ষণের জন্য সূক্ষ্ম কাজ করে, আপনি এনএসআরকিভার / এনএসকিডআরচিভারের সাথে স্ট্রাক্ট যুক্ত কোনও এনএসভ্যালুকে এনকোড করতে পারবেন না। পরিবর্তে, আপনাকে পৃথক স্ট্রাক্ট সদস্যদের এনকোড করতে হবে ...

দেখুন অ্যাপলের আর্কাইভস এন্ড Serializations প্রোগ্রামিং গাইড> কাঠামো এবং বিট ক্ষেত্রসমূহ


0

আপনার কাঠামোর জন্য আপনি একটি বৈশিষ্ট্য যুক্ত করতে পারেন objc_boxableএবং @()কল না করে আপনার স্ট্রাকচারের এনএসওয়ালু উদাহরণটিতে সিনট্যাক্স ব্যবহার করতে পারেন valueWithBytes:objCType::

typedef struct __attribute__((objc_boxable)) _Megapoint {
    float   w,x,y,z;
} Megapoint;

NSMutableArray<NSValue*>* points = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i+= 1) {
    Megapoint mp1 = {i + 1.0, i + 2.0, i + 3.0, i + 4.0};
    [points addObject:@(mp1)];//@(mp1) creates NSValue*
}

Megapoint unarchivedPoint;
[[points lastObject] getValue:&unarchivedPoint];
//or
// [[points lastObject] getValue:&unarchivedPoint size:sizeof(Megapoint)];

-2

একটি ওজেজে সি অবজেক্ট কিছু যুক্ত উপাদানগুলির সাথে একটি সি কাঠামো। সুতরাং কেবল একটি কাস্টম ক্লাস তৈরি করুন এবং আপনার কাছে এনএসএর্রে প্রয়োজনীয় সি স্ট্রাক্টের ধরণ থাকবে। যে কোনও সি স্ট্রাক্টের কোনও এনএসওবজেক্ট তার সি স্ট্রাক্টের মধ্যে অন্তর্ভুক্ত অতিরিক্ত ক্রাফট না করে কোনও এনএসআরির জন্য অজীর্ণ হবে।

এনএসডিটা কে একটি মোড়ক হিসাবে ব্যবহার করা কেবল স্ট্রাক্টের অনুলিপি সংরক্ষণ করতে পারে এবং মূল স্ট্রাক্টগুলি নয়, যদি এটি আপনার পক্ষে কোনও পার্থক্য করে।


-3

তথ্য সংরক্ষণের জন্য আপনি সি-কাঠামো ব্যতীত অন্য এনএসবজেক্ট ক্লাস ব্যবহার করতে পারেন। এবং আপনি সহজেই সেই এনএসওবজেক্টটিকে এনএসআরেতে সঞ্চয় করতে পারেন।

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