এনএসউজারডেফল্টস কেন আইওএস-এ এনএসএমটেবাল ডিকোরিয়ালিটি সংরক্ষণ করতে ব্যর্থ হয়েছিল?


145

আমি একজন সংরক্ষণ করতে চাই NSMutableDictionaryবস্তুর NSUserDefaults। মূল প্রকারটি NSMutableDictionaryহ'ল NSString, মান টাইপ NSArray, যা অবজেক্টের একটি তালিকা রয়েছে যা প্রয়োগ করে NSCoding। প্রতি দস্তাবেজ, NSStringএবং NSArrayউভয়ই অনুসারে NSCoding

আমি এই ত্রুটি পাচ্ছি:

[এনএসউসারডেফাল্টস সেটঅবজেক্ট: ফরকি:]: এনএসসিএফড্রেসিয়ান ক্লাসের অ-সম্পত্তি মান .... সন্নিবেশ করার চেষ্টা করা হয়েছে।

উত্তর:


230

আমি একটি বিকল্প খুঁজে পেয়েছি, সংরক্ষণের আগে, আমি NSArrayব্যবহার করে মূল বস্তু ( বস্তু) এনকোড করেছি NSKeyedArchiver, যা শেষ হয় NSData। তারপরে ব্যবহারকারীর ডেফল্টগুলি সংরক্ষণ করুন NSData

আমার যখন ডেটা দরকার তখন আমি পড়ি NSDataএবং অবজেক্টে ফিরে NSKeyedUnarchiverরূপান্তর করতে ব্যবহার করি NSData

এটি একটু কষ্টকর, কারণ আমাকে NSDataপ্রতিবার থেকে / থেকে রূপান্তর করতে হবে তবে এটি কেবল কার্যকর।

অনুরোধ অনুযায়ী এখানে একটি উদাহরণ:

সংরক্ষণ:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arr = ... ; // set value
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[defaults setObject:data forKey:@"theKey"];
[defaults synchronize];

ভার:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

অ্যারে প্রয়োগকারী উপাদান

@interface CommentItem : NSObject<NSCoding> {
    NSString *value;
}

তারপরে বাস্তবায়নে CommentItemদুটি পদ্ধতি সরবরাহ করা হয়:

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:value forKey:@"Value"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    self.value = [decoder decodeObjectForKey:@"Value"];
    return self;
}

এর চেয়ে ভাল সমাধান কারও আছে?

ধন্যবাদ সবাইকে.


4
আপনার কাছে ভাগ করার মতো কোনও কোডের নমুনা রয়েছে, আমি পোস্টে এটি করার চেষ্টা করছি (537044) তবে কোনও আনন্দের সাথে নয়
অ্যান্টনি মেইন

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

লোড হওয়া বস্তুটি কখন প্রকাশ করতে হবে? কোন বরাদ্দ বলা হয়নি, তাই আমি এটি স্বাবলম্বিত বলে ধরে নেব?
মার্ক

7
আমাদের সাশ্রয় করার জন্য [ডিফল্ট সিঙ্ক্রোনাইজ] যুক্ত করতে পারে
থানহ্বিনহ 84৪

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

105

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

অবগতির জন্য সম্পত্তি তালিকা ক্লাস আছে NSDictionary, NSArray, NSString, NSDate, NSData, এবং NSNumber। আপনি NSMutableDictionaryব্যবহারকারীর পছন্দগুলিতে পরিবর্তনীয় উপশ্রেণী (যেমন ) লিখতে পারেন তবে আপনি যে জিনিসগুলি পড়েছেন তা সর্বদা অপরিবর্তনীয়।


61
আমার আরও উল্লেখ করতে হবে যে কীগুলি এনএসএসটিংস হয় তবে কোনও এনএসডি অভিধানটি কেবল একটি সম্পত্তি তালিকার অবজেক্ট। সাধারণভাবে আপনি অভিধান কী হিসাবে অন্যান্য অবজেক্ট ব্যবহার করতে পারেন, তবে যেখানে সম্পত্তি তালিকার প্রয়োজন সেখানে কীগুলি অবশ্যই স্ট্রিং হওয়া উচিত।
টম হ্যারিংটন

আমি একই সমস্যার মুখোমুখি হয়েছি, যখন আমি এনএসআরএলটিকে কোনও এনএসডি অভিধানে একটি বস্তুরূপে সঞ্চয় করতে এবং এনএসউজারডেফাল্টগুলিতে সঞ্চয় করতে চাইতাম। আমাকে এটিকে এনএসএসস্ট্রিং-তে পরিবর্তন করতে হয়েছিল, এটি কাজ করার চেয়ে বেশি।
নিকটেসলা

1
গ্রেট! আমার ক্ষেত্রে, আমি ব্যবহারকারীর ডিফল্টগুলিতে NSNumber ব্যবহার করার চেষ্টা করেছি। আমাকে এটিকে একটি এনএসএস স্ট্রিংয়ে পরিবর্তন করতে হবে।
জয়ে

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

14

অভিধানে কি সব আপনার কী আছে NSString? আমি মনে করি কোনও সম্পত্তি তালিকায় অভিধান সংরক্ষণ করার জন্য তাদের থাকতে হবে।


1
কীগুলি এনএসএসস্ট্রিং। তবে মানটি হ'ল এনএসআর্রে, যার উপাদানটি একটি অনুকূলিত শ্রেণি যা এনএসকোডিং প্রয়োগ করে। এটি প্রদর্শিত হয় যে সমাধানটি কাজ করছে না কারণ ইউজারডেফাল্টগুলি কেবল 6 ধরণের শ্রেণিকে সমর্থন করে, এনএসকোডিং বিবেচনা করবেন না।
ব্লুডলফিন 21

8

সহজ উত্তর:

NSDictionaryকীগুলি যদি এনএসএসআরটিং হয় তবে কেবলমাত্র একটি প্লিস্ট অবজেক্ট । সুতরাং, সঞ্চয় করুন "কী" হিসাবে সঙ্গে ।NSStringstringWithFormat


সমাধান:

NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];

উপকারিতা:

  1. এটি স্ট্রিং-মান যুক্ত করবে ।
  2. আপনার ভেরিয়েবলের মান হ'লে এটি খালি মূল্য যুক্ত করবে NULL

2
আমার অনুরূপ সমস্যা ছিল: আমার কীগুলি এনএসএন নাম্বার ছিল, যা সম্ভবত প্লাস্ট অভিধানের কীগুলিতে অনুমোদিত নয়।
মার্ক পাউলি

5

আপনি কি NSCodingপ্রোটোকলটি প্রয়োগের দিকে তাকিয়ে বিবেচনা করেছেন ? এটি আপনাকে আইফোনটিতে দুটি সহজ পদ্ধতির সাথে এনকোড এবং ডিকোড করতে সহায়তা করবে যা এর সাথে প্রয়োগ করা হয় NSCoding। প্রথমে আপনাকে NSCodingআপনার ক্লাসে যুক্ত করতে হবে ।

এখানে একটি উদাহরণ:

এটি .h ফাইলে রয়েছে

@interface GameContent : NSObject <NSCoding>

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

    - (id) initWithCoder: (NSCoder *)coder
    {
        if (self = [super init])
        {
               [self setFoundHotSpots:[coder decodeObjectForKey:@"foundHotSpots"]];
        }
        return self;
    }

    - (void) encodeWithCoder: (NSCoder *)coder
    {
           [coder encodeObject:foundHotSpots forKey:@"foundHotSpots"];
    }

আরও তথ্যের জন্য এনএসকোডারে ডকুমেন্টেশন দেখুন। এটি আমার প্রকল্পগুলির জন্য সত্যই কার্যকর হয়েছে যেখানে অ্যাপ্লিকেশনটি বন্ধ থাকলে আইফোনটিতে অ্যাপ্লিকেশনের অবস্থাটি সংরক্ষণ করতে হবে এবং তার পিছনে ফিরে যাওয়ার পরে এটি পুনরায় ফিরিয়ে আনতে হবে।

কী ইন্টারফেসে প্রোটোকল যোগ করার জন্য এবং তারপর দুই পদ্ধতি অংশ বাস্তবায়ন হয় NSCoding

আশা করি এটা কাজে লাগবে!


0

এর চেয়ে ভাল সমাধান আর নেই। অন্য বিকল্পটি কেবল কোডড অবজেক্টটি ডিস্কে সংরক্ষণ করা হবে - তবে এটি একই কাজ করছে is তারা উভয়ই এনএসডিটাতে শেষ হয় যা আপনি যখন এটি চান তখন ডিকোড হয়ে যায়।

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