আমি কীভাবে অবজেক্টিভ-সি-তে একটি সারি তৈরি করব এবং ব্যবহার করব?


107

আমি আমার উদ্দেশ্য-সি প্রোগ্রামে একটি সারি ডেটা কাঠামো ব্যবহার করতে চাই। সি ++ এ আমি এসটিএল সারিটি ব্যবহার করতাম। অবজেক্টিভ-সি সমতুল্য ডেটা স্ট্রাকচার কী? আমি কীভাবে পপ / পপ আইটেমগুলি ঠেকাতে পারি?

উত্তর:


153

বেনের সংস্করণটি একটি সারির পরিবর্তে একটি স্ট্যাক, তাই আমি এটি কিছুটা টুইট করেছি:

NSMutableArray + + QueueAdditions.h

@interface NSMutableArray (QueueAdditions)
- (id) dequeue;
- (void) enqueue:(id)obj;
@end

NSMutableArray + + QueueAdditions.m

@implementation NSMutableArray (QueueAdditions)
// Queues are first-in-first-out, so we remove objects from the head
- (id) dequeue {
    // if ([self count] == 0) return nil; // to avoid raising exception (Quinn)
    id headObject = [self objectAtIndex:0];
    if (headObject != nil) {
        [[headObject retain] autorelease]; // so it isn't dealloc'ed on remove
        [self removeObjectAtIndex:0];
    }
    return headObject;
}

// Add to the tail of the queue (no one likes it when people cut in line!)
- (void) enqueue:(id)anObject {
    [self addObject:anObject];
    //this method automatically adds to the end of the array
}
@end

আপনি নিজের নতুন পদ্ধতিগুলি যেখানেই ব্যবহার করতে চান সেখানে কেবল .h ফাইলটি আমদানি করুন এবং আপনার যেমন কোনও NSMutableArray পদ্ধতি আছে তেমন কল করুন।

শুভকামনা এবং কোডিং চালিয়ে যান!


1
যারা শূন্য সারি থেকে শত্রু হওয়ার চেষ্টা করার সময় ব্যতিক্রম করার পরিবর্তে শূন্যতার দিকে ফিরে যেতে চান তাদের জন্য প্রসূতির শুরুতে একটি মন্তব্য-আউট লাইন যুক্ত করেছি added আইএমও, ব্যতিক্রম বাড়াতে NSMutableArray আচরণ অনুসরণ কোকো সঙ্গে আরও সামঞ্জস্যপূর্ণ। সর্বোপরি, -countডিকুইউ করার মতো কোনও বস্তু আছে কিনা তা পরীক্ষা করতে আপনি আগেই কল করতে পারেন । সত্যিই এটি পছন্দ করার বিষয়।
কুইন টেলর

2
আমি এই কোডটি গিথুব রেপোতে যুক্ত করেছি। কাঁটাচামচা নির্দ্বিধায় বা আমাকে কিছু ভুল হয়েছে কিনা তা আমাকে জানান: github.com/esromneb/ios-queue-object ধন্যবাদ !!!
পোর্টফোর্ডওয়ার্ডপডকাস্ট

2
আমি কি কিছু মিস করছি, বা এই বাস্তবায়নের ক্ষেত্রে (ণ) জটিলতার জটিলতা রয়েছে? এটা ভয়ানক। আপনি একটি বিজ্ঞপ্তি অ্যারের প্রয়োগের সাথে আরও ভাল হতে চাই। এই প্রয়োগটি কার্যকর হতে পারে, তবে ও (এন) ডিকুইয়ের ধারণাটি বেদনাদায়ক।
ThatGuy

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

2
@ থ্যাটগুই কিছুটা দেরি করে, তবে এনএসআরাই একটি বিজ্ঞপ্তি বাফার দিয়ে প্রয়োগ করা হয়েছে, তাই রানটাইম থেটা (এন) হবে না।
hhanesand

33

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

কোকোতে একটি অন্তর্নির্মিত নেই, তবে অন্যান্য বিকল্প রয়েছে, এবং আপনাকে স্ক্র্যাচ থেকে একটিও লিখতে হবে না। সত্যিকারের সারির জন্য যা কেবল প্রান্তগুলি থেকে যোগ এবং সরিয়ে দেয়, একটি বিজ্ঞপ্তি বাফার অ্যারে একটি অত্যন্ত দ্রুত বাস্তবায়ন। সিএইচডিটাস্ট্রাকচারস.ফ্রেমেওয়ার্ক , ওপজেক্টিভ -সি-তে একটি লাইব্রেরি / ফ্রেমওয়ার্ক যা আমি কাজ করছি Check এটা তোলে সারিগুলি, সেইসাথে স্ট্যাকগুলি, deques, সাজানো সেট, ইত্যাদি আপনার উদ্দেশ্যে এর বাস্তবায়নের বিভিন্ন আছে, CHCircularBufferQueue উল্লেখযোগ্যভাবে দ্রুততর (অর্থাত benchmarks সঙ্গে প্রতিপাদ্য) এবং আরো পাঠযোগ্য (বোঝা যাচ্ছে যে নেতারা বিষয়ী) একজন NSMutableArray ব্যবহার করে।

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

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


2
খুশি যে কেউ সত্যই একটি সারি সলিউশন দিয়ে উত্তর দিয়েছে
কেসব্যাশ

সমস্ত লিঙ্কগুলি নষ্ট হয়ে গেছে - আমি সেই কাঠামোটি কোথায় পাব? আমি এ সম্পর্কে অনেক ভাল জিনিস পড়েছি কিন্তু আসল কোডটি খুঁজে পাচ্ছি না!
amok

কাঠামোটি আশাব্যঞ্জক মনে হলেও এসভিএন-এর লিঙ্কগুলি এখনও ভাঙা। কোথাও কোড পাওয়ার কোনও সুযোগ? সম্পাদনা: এটি mac.softpedia.com/progDownload/… থেকে পেয়েছি তবে এটি বর্তমান সংস্করণ কিনা তা আমি দেখতে পাচ্ছি না
কেয়ার

ডেভ দেলংয়ের গিট রেপো ক্লোনটি এখনকার দিনে যেতে যাওয়া রেপো হিসাবে উপস্থিত হবে।
রিজেক্সিডেন্ট

29

যতদূর আমি জানি, অবজেক্টিভ-সি কোনও সারি ডাটা স্ট্রাকচার সরবরাহ করে না। আপনার সেরা বাজি একটি তৈরি করা NSMutableArray, এবং তারপর ব্যবহার [array lastObject], [array removeLastObject]আইটেম আনতে, এবং [array insertObject:o atIndex:0]...

আপনি যদি এটি অনেক কিছু করে থাকেন তবে NSMutableArrayক্লাসের কার্যকারিতা বাড়িয়ে দিতে আপনি একটি উদ্দেশ্য-সি বিভাগ তৈরি করতে চাইতে পারেন । বিভাগগুলি আপনাকে বিদ্যমান ক্লাসগুলিতে গতিশীলভাবে ফাংশন যুক্ত করতে দেয় (এমনকি আপনার কাছে যার উত্স নেই) - আপনি এটির মতো একটি সারি তৈরি করতে পারেন:

(দ্রষ্টব্য: এই কোডটি আসলে একটি স্ট্যাকের জন্য, একটি সারি নয় below নীচের মন্তব্য দেখুন)

@interface NSMutableArray (QueueAdditions)

- (id)pop;
- (void)push:(id)obj;

@end

@implementation NSMutableArray (QueueAdditions)

- (id)pop
{
    // nil if [self count] == 0
    id lastObject = [[[self lastObject] retain] autorelease];
    if (lastObject)
        [self removeLastObject];
    return lastObject;
}

- (void)push:(id)obj
{
     [self addObject: obj];
}

@end

7
আপনি কি জানেন যে আপনি এখানে একটি স্ট্যাক প্রয়োগ করেছেন, একটি সারি নেই?
জিম পালস

আহ - দুঃখিত! - নীচে ওল্ফকো এর পরিবর্তনগুলি দেখুন।
বেন গোটো

আপনি যদি "সেরা বিকল্প" এর সাথে "সবচেয়ে সহজ বিকল্প" দিয়ে প্রতিস্থাপন করেন তবে আমি সম্মত হব :-) ডেটা স্ট্রাকচার পিউরিস্ট এবং পারফরম্যান্স অবসেসররা সত্যিকারের সারি পছন্দ করবে তবে একটি এনএসমিটেবলআরারি সহজেই একটি কাতারে দাঁড়াতে পারে।
কুইন টেলর

3
বেন করার জন্য +1 কারণ আমি একটি স্ট্যাকের সমাধান চাইছিলাম যদিও একটি সারি জিজ্ঞাসা করা হয়েছিল :)
হুইটনিল্যান্ড

আমি যা ভাবতে পারি তার ব্যথা। আপনি একটি অ্যারের শুরুতে একটি বস্তু সন্নিবেশ করছেন, তারপরে প্রতিবার আপনি timeোকাবার সময় প্রতিটি উপাদানকে 1 স্পেসের বেশি অনুলিপি করতে হবে। এই ক্ষেত্রে একটি লিঙ্কযুক্ত-তালিকা আরও ভাল সঞ্চালন করবে।
TheM00s3

8

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


সত্য, একটি NSMutableArray একটি সুন্দর শালীন সারি তৈরি করে, যদিও সামনে থেকে সরানো কোনও অ্যারে কাঠামোকে ছাড়িয়ে যায় এমন কিছু নয়। তবুও, ছোট সারিগুলির জন্য, কার্য সম্পাদন কোনওভাবেই বড় উদ্বেগ নয়। আমার এক বন্ধু কিছুক্ষণ আগে এই বিষয়টি নিয়ে ব্লগ করেছে ... sg80bab.blogspot.com/2008/05/…
কুইন টেলর

7

হ্যাঁ, NSMutableArray ব্যবহার করুন। এনএসমুটেবলআরে আসলে বাস্তবায়িত হয় 2-3 গাছ হিসাবে; স্বেচ্ছাসেবক সূচকগুলিতে NSMutableArray থেকে অবজেক্ট যোগ করার বা অপসারণের পারফরম্যান্স বৈশিষ্ট্যগুলির সাথে নিজেকে সাধারণত উদ্বেগের দরকার নেই।


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

5

পুনরায়: ওল্ফকো - এখানে ওল্ফকোয়ের ডেকিউ পদ্ধতির একটি সঠিক সংশোধন করা হয়েছে

- (id)dequeue {
    if ([self count] == 0) {
        return nil;
    }
    id queueObject = [[[self objectAtIndex:0] retain] autorelease];
    [self removeObjectAtIndex:0];
    return queueObject;
}

4

যে বিভাগগুলিতে কোনও বিভাগ ব্যবহার করা হয় NSMutableArrayসেগুলি সত্যিকারের সারি নয়, কারণ NSMutableArrayক্রিয়াকলাপগুলি উন্মুক্ত করে যেগুলি সারিগুলির একটি সুপারসেট। উদাহরণস্বরূপ, আপনাকে কিউয়ের মাঝামাঝি থেকে কোনও আইটেম সরানোর অনুমতি দেওয়া উচিত নয় (যেমন বিভাগগুলির সমাধানগুলি আপনাকে এখনও করতে দেয়)। অবজেক্ট ওরিয়েন্টেড ডিজাইনের একটি প্রধান নীতি, কার্যকারিতা সজ্জিত করা ভাল।

StdQueue.h

#import <Foundation/Foundation.h>

@interface StdQueue : NSObject

@property(nonatomic, readonly) BOOL empty;
@property(nonatomic, readonly) NSUInteger size;
@property(nonatomic, readonly) id front;
@property(nonatomic, readonly) id back;

- (void)enqueue:(id)object;
- (id)dequeue;

@end

StdQueue.m

#import "StdQueue.h"

@interface StdQueue ()

@property(nonatomic, strong) NSMutableArray* storage;

@end

@implementation StdQueue

#pragma mark NSObject

- (id)init
{
    if (self = [super init]) {
        _storage = [NSMutableArray array];
    }
    return self;
}

#pragma mark StdQueue

- (BOOL)empty
{
    return self.storage.count == 0;
}

- (NSUInteger)size
{
    return self.storage.count;
}

- (id)front
{
    return self.storage.firstObject;
}

- (id)back
{
    return self.storage.lastObject;
}

- (void)enqueue:(id)object
{
    [self.storage addObject:object];
}

- (id)dequeue
{
    id firstObject = nil;
    if (!self.empty) {
        firstObject  = self.storage.firstObject;
        [self.storage removeObjectAtIndex:0];
    }
    return firstObject;
}

@end

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

3

এটি আমার বাস্তবায়ন, আশা করি এটি সহায়তা করবে।

একধরনের সংক্ষিপ্তসার, সুতরাং আপনাকে অবশ্যই নতুন মাথাটি পপ এ সংরক্ষণ এবং পুরানো মাথাটি ত্যাগ করে মাথার ট্র্যাক রাখতে হবে

@interface Queue : NSObject {
    id _data;
    Queue *tail;
}

-(id) initWithData:(id) data;
-(id) getData;

-(Queue*) pop;
-(void) push:(id) data;

@end

#import "Queue.h"

@implementation Queue

-(id) initWithData:(id) data {
    if (self=[super init]) {
        _data = data;
        [_data retain];
    }
    return self;
}
-(id) getData {
    return _data;
}

-(Queue*) pop {
    return tail;
}
-(void) push:(id) data{
    if (tail) {
        [tail push:data];
    } else {
        tail = [[Queue alloc]initWithData:data];
    }
}

-(void) dealloc {
    if (_data) {
        [_data release];
    }
    [super release];
}

@end

2

আপনি কেবল এসটিএল সারিটি ব্যবহার করতে পারবেন না এমন কোনও বিশেষ কারণ রয়েছে? অবজেক্টিভ সি ++ হ'ল সি ++ এর একটি সুপারসেট (অবজেক্টিভ সি এর পরিবর্তে অবজেক্টিভ সি ++ ব্যবহার করার জন্য .m এর পরিবর্তে কেবলমাত্র মিমি ব্যবহার করুন)। তারপরে আপনি এসটিএল বা অন্য কোনও সি ++ কোড ব্যবহার করতে পারেন।

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


1
এটি আসলে একটি ভাল ধারণা বলে মনে হচ্ছে না ... কারণ আপনি কিছু করতে পারেন তার অর্থ আপনার উচিত নয়। কেবল একটি সারি শ্রেণির জন্য পুরো এসটিএল এবং সি ++ বাস্তুতন্ত্রের দিকে টান হ'ল অবশ্যই ওভারকিল।
এক্সট্রপিক ইঞ্জিন

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

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