নতুন পরিবর্তে বরাদ্দ init ব্যবহার করুন


344

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

SomeObject *myObject = [[SomeObject alloc] init];

পরিবর্তে:

SomeObject *myObject = [SomeObject new];

এগুলির কি কোনও কারণ আছে, যেমন আমি পড়েছি যে তারা সমান?


12
আমি জানি না যে এটি সম্ভব! আমি যে সমস্ত উপাদান পড়েছি তা নতুন কীওয়ার্ডের অস্তিত্বের মতো ভান করে!
জোনাথন

78
প্রকৃতপক্ষে "নতুন" উদ্দেশ্যমূলক-সি-তে কোনও কীওয়ার্ড নয়, তবে এনএসবজেক্ট একটি শ্রেণিবদ্ধ পদ্ধতি "নতুন" প্রয়োগ করে যা কেবল "বরাদ্দ" এবং "init" বলে calls
ডন ম্যাককোহে

3
জোনাথন, ঠিক এটাই আমার প্রশ্নকে উত্সাহিত করেছিল। এগুলি কার্যকরীভাবে সমতুল্য হতে পারে তবে [[বরাদ্দ] init] স্পষ্টতই প্রভাবশালী রীতিমতো।
willc2

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

উত্তর:


290

এখানে অনেকগুলি কারণ রয়েছে:

কিছু নির্বাচিতগুলি হলেন:

  • newকাস্টম প্রারম্ভক (যেমন initWithString) সমর্থন করে না
  • alloc-init তুলনায় আরও স্পষ্ট হয় new

সাধারণ মতামত থেকে মনে হচ্ছে আপনি যেটি স্বাচ্ছন্দ্যযুক্ত তা আপনার ব্যবহার করা উচিত।


8
যদি আপনার শ্রেণি নির্ধারিত আরম্ভকারী হিসাবে ইন-আইট ব্যবহার করে, + নতুন এটি কল করবে। জেরেমি যা উল্লেখ করছেন তা হ'ল যদি আপনার কাছে একটি কাস্টম ইনিশিয়ালাইজার থাকে যা -ইন না। -initWithName: উদাহরণস্বরূপ।
বুবুম

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

11
আমি জানি এটি একটি পুরানো থ্রেড, তবে আমি কেবল চাপ দিতে চাই যাতে আপনার প্রয়োগ করা উচিত নয়+newWithString: । এটি উদ্বেগের বিচ্ছেদ ভাঙা। আপনি যখন -initযেভাবেই ব্যবহার করতে চান, কেবলমাত্র ব্যবহার না করার কোনও কারণ নেই +new
জোনাথন স্টার্লিং

7
@ জোনাথন স্টার্লিং: অ্যাপলের এমন অনেকগুলি উদাহরণ রয়েছে যেখানে তারা আপনার বিরুদ্ধে পরামর্শ দেওয়ার মতো কাজটি করে যাচ্ছেন বলে মনে হয়; উদাহরণস্বরূপ [[NSString alloc] initWithFormat:...]এবং [NSString stringWithFormat:...]উভয় সমতুল্য। আপনি কি বলছেন অ্যাপল উদ্বেগের পৃথকীকরণ লঙ্ঘন করেছে এবং এটিকে এভাবে প্রয়োগ করা উচিত হয়নি? (দ্রষ্টব্য: আমি কৃপণ হওয়ার চেষ্টা করছি না; আমি কেবল আরও তথ্য পেতে চাই এবং অ্যাপলের নেতৃত্ব অনুসরণ করা কখনও কখনও খারাপ ধারণা হয় কিনা তা জানতে চাই))
সেনসফুল

6
@ সেনসফুল আমি বিশ্বাস করি যে এটিআরসি (বা আবর্জনা সংগ্রহের) আগের দিনগুলির dates এই দুটি জিনিস আমরা সমতুল্য না। স্ট্রিংউইথফর্ম্যাট: বরাদ্দকালে একটি স্বতঃপ্রযুক্ত স্ট্রিং ফিরিয়ে আনবে: init: ম্যানুয়ালি প্রকাশ করা বা স্বাবলম্বী হওয়া দরকার, অন্যথায় এটি মেমরি ফাঁসের কারণ হতে পারে।
মিসফেল্ডস্টেইন

139

খুব পুরানো প্রশ্ন, তবে আমি কেবল মজাদার জন্য কিছু উদাহরণ লিখেছি - সম্ভবত আপনি এটি দরকারী খুঁজে পাবেন;)

#import "InitAllocNewTest.h"

@implementation InitAllocNewTest

+(id)alloc{
    NSLog(@"Allocating...");
    return [super alloc];
}

-(id)init{
    NSLog(@"Initializing...");
    return [super init];
}

@end

প্রধান কার্য উভয় বিবৃতি:

[[InitAllocNewTest alloc] init];

এবং

[InitAllocNewTest new];

একই আউটপুট ফলাফল:

2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating...
2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...

5
দুর্দান্ত উত্তর! শুধু যুক্ত করতে চাই যে + নতুন ব্যবহার করা সেই ক্ষেত্রে ক্ষেত্রে দুর্দান্ত যেখানে আপনার কেবলমাত্র -init ব্যবহার করতে হবে এবং এর মতো আরও কিছু বিশেষায়িত কিছু নয়: ...
cgossain

দুর্ভাগ্যক্রমে, এই উদাহরণটি প্রমাণ নয় যে তারা অভিন্ন। এটি একই উদাহরণ যেখানে তারা একই ফলাফল দেয়।
ভিন্স ও'সুলিভান

10
দুর্ভাগ্যক্রমে, এই উদাহরণটি প্রমাণ নয় যে তারা অভিন্ন। এটি কেবল উদাহরণ যেখানে তারা ঘটে একই ফলাফল তৈরি করে produce অন্যদিকে, এটি প্রমাণ করে যে তারা আলাদা ... @end সংক্রামিত [[InitAllocNewTest alloc] init]হবে না যতক্ষণ না [InitAllocNewTest new]প্রভাবিত। (লাইনের বিরতি ইত্যাদির অভাবে ক্ষমা প্রার্থনা)
ভিন্স ও'সুলিভান

1
@ ভিনসও সুলিভান, ভাল কথা। এর অর্থ যদি কেউ সিআইএনটি অনুপলব্ধ করে তুলতে চায়, যেমন একটি একক ক্লাসে, তবে নতুনকেও অক্ষম করা উচিত। সিলেটলেটগুলি ভাল না খারাপ সে বিষয়ে আমি এখানে স্পর্শ করব না।
ব্যবহারকারীর 3099609

উপরের কোড থেকে আমার একটি প্রশ্ন আছে। কেন "ফিরুন [সুপার থ্রি]"? " সাধারনত init একটি পদ্ধতি যেখানে ক্লাসের সদস্যদের সূচনা করা হয়, কেন পয়েন্টার পরিবর্তনগুলি খুব অদ্ভুত!
পৃথ্বিধর রাও নাদুনুরু

52

+new+alloc/-initঅ্যাপলের NSObjectবাস্তবায়নের সমতুল্য । এটি কখনই পরিবর্তিত হবে এমন সম্ভাবনা খুব কম তবে আপনার প্যারানোইয়া স্তরের উপর নির্ভর করে আপেলের ডকুমেন্টেশন +newভবিষ্যতে বাস্তবায়নের পরিবর্তনের (এবং সমতা ভেঙে) মঞ্জুরি দেয় বলে মনে হয়। এই কারণে, "সুস্পষ্ট বর্ণিত চেয়ে ভাল" এবং historicalতিহাসিক ধারাবাহিকতার জন্য, উদ্দেশ্য-সি সম্প্রদায় সাধারণত এড়িয়ে চলে +new। আপনি তবে সাধারণভাবে সাম্প্রতিক জাভা আগতদের উদ্দেশ্যযুক্ত সি দ্বারা অবজেক্টিভ-সি-তে স্পট করতে পারেন +new


8
যদিও এটি প্রায়শই সত্য হয়, তত্পরতার পক্ষেও একটি শিবির রয়েছে, যার ক্ষেত্রে এটির স্পষ্ট এবং বর্তমান উদ্বেগ থাকলে কেবল তখনই আরও স্পষ্ট হয়।
পিটার ডিউইজ

27
আমি এটিকে হ্রাস করেছি কারণ +newNeXT দিন থেকে প্রায় ছিল। যদি কিছু +newএমন কিছু ব্যক্তির লক্ষণ যা কিছুদিন আগে অবজেক্ট শিখেছে; আমি অনেক লোককে দেখতে পাই যারা এই ভাষাতে নতুনভাবে আসে, বা যারা বছরের পর বছর ধরে এটি লিখে চলেছে তবে স্পষ্টভাবে আইওএস বুমের পরে, তাদের +newঅর্থ কী তা জানা নেই । দ্বিতীয়ত, যেমনটি +newঅনেক পুরাতন এবং নেক্সটি দিনের থেকে, অ্যাপল এটিকে এমনভাবে পরিবর্তন করা বেশ পাগল হতে পারে যাতে বিশেষত তাদের নিজস্ব কোড বেসগুলি সম্ভবত এটির সাথে আবদ্ধ থাকে considering
asveikau

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

3
এটি কেবল বরাদ্দ পরিবর্তনের অনুমতি দেয়। দস্তাবেজগুলি স্পষ্টভাবে রাজ্যে -আইনাইটে ডাকা হবে। সুতরাং আপনি যদি কখনও বরাদ্দকে ওভাররাইড করেন তবে এটি আরও নির্ভর করে।
কেন্ডল হেলস্টেটার জেলনার

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

9

প্রায়শই আপনাকে আর্গুমেন্টগুলি পাস initকরতে হবে এবং সুতরাং আপনি কোনও আলাদা পদ্ধতি ব্যবহার করবেন [[SomeObject alloc] initWithString: @"Foo"]। আপনি যদি এটি লিখতে অভ্যস্ত হন তবে আপনি এটি এইভাবে করার অভ্যাস পান এবং তাই [[SomeObject alloc] init]স্বাভাবিকভাবেই এটি আসতে পারে [SomeObject new]


7

একটি সংক্ষিপ্ত উত্তর:

  1. দুটোই এক। কিন্তু
  2. 'নতুন' কেবলমাত্র 'প্রাথমিক' ইনিশিয়ালাইজারের সাথে কাজ করে এবং অন্যান্য ইনিশিয়ালাইজারের সাথে কাজ করবে না (উদাহরণস্বরূপ initWithString :)।

3

পার্শ্ব নোটের জন্য, আমি ব্যক্তিগতভাবে এটি ব্যবহার করি [Foo new]যদি আমি এর কোনও জায়গায় এর রিটার্ন মানটি ব্যবহার না করে আরম্ভের কিছু করা উচিত। আপনি যদি [[Foo alloc] init]কোথাও ফেরত না ব্যবহার করেন তবে আপনি একটি সতর্কতা পাবেন। কম বেশি, আমি [Foo new]আই ক্যান্ডির জন্য ব্যবহার করি ।


3

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


1

যদি নতুন আপনার জন্য কাজ করে তবে তা আপনার কোডটিকেও খুব ছোট করে তুলবে। আপনি যদি অন্যথায় [[SomeClass alloc] init]আপনার কোডের বিভিন্ন জায়গায় কল করতে চান তবে আপনি নতুন প্রয়োগের জন্য একটি হট স্পট তৈরি করবেন - এটি হ'ল অবজেক্ট রানটাইম - যা আপনার ক্যাশে মিস করার সংখ্যা হ্রাস করবে।

আমার বোঝার মধ্যে, আপনার যদি কাস্টম আরম্ভকারী ব্যবহারের প্রয়োজন হয় [[SomeClass alloc] initCustom]

আপনি যদি না, ব্যবহার [SomeClass new]


1
আমি "আপনার যদি কাস্টম ইনিশিয়ালাইজার ব্যবহার [[সামার ক্লাস বরাদ্দ] initCustom] ব্যবহার করা প্রয়োজন" সাথে তর্ক করব। আপনার যদি কোনও প্যারামিটার ছাড়াই কাস্টম ইনিশিয়েলজারের প্রয়োজন হয় তবে আপনার পরামর্শ মতো কিছু কখনই করবেন না, কেবলমাত্র ডিফল্ট initফাংশনটি ওভাররাইড করুন এবং এটি ব্যবহার করুন আপনার [[SomeClass alloc] init];যদি প্যারামিটারগুলির প্রয়োজন হয় তবে এখনও এর মতো কিছু করবেন না, করুন [[SomeClass alloc] initWith:...];। সবশেষে, আপনি যদি initকাস্টম প্রয়োগের সাথে ফাংশনটিকে ওভাররাইড করে থাকেন তবে আপনি newকোনও অবজেক্ট তৈরি করার জন্য কল করতে পারেন এবং এটি এখনও কাস্টম initবাস্তবায়নকে কল করবে ।
নোংরাডানি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.