উদ্দেশ্য-সি: এনএসএনটিফিকেশন জন্য পর্যবেক্ষক কোথায় সরান?


102

আমার একটি উদ্দেশ্য সি ক্লাস আছে। এটিতে আমি একটি ডিআইডি পদ্ধতি তৈরি করেছি এবং এটিতে একটি এনএসনিটিফিকেশন সেট আপ করেছি

//Set up NSNotification
[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(getData)
                                             name:@"Answer Submitted"
                                           object:nil];

আমি [[NSNotificationCenter defaultCenter] removeObserver:self]এই ক্লাসে কোথায় সেট করব ? আমি জানি যে UIViewControllerএটির জন্য, আমি এটি viewDidUnloadপদ্ধতিতে যুক্ত করতে পারি তাই যদি আমি কেবল একটি উদ্দেশ্য সি শ্রেণি তৈরি করি তবে কী করা দরকার?


আমি এটি ডেলোক পদ্ধতিতে রেখেছি।
onnoeb

1
আমি যখন উদ্দেশ্য সি শ্রেণি তৈরি করেছি তখন ডেলোক পদ্ধতিটি স্বয়ংক্রিয়ভাবে আমার জন্য তৈরি করা হয়নি, সুতরাং এটি যুক্ত করা কি আমার পক্ষে ঠিক?
ঝেন

হ্যাঁ, আপনি এটি প্রয়োগ করতে পারেন -(void)deallocএবং তারপরে removeObserser:selfএটি যুক্ত করতে পারেন । এটি রাখার সর্বাধিক প্রস্তাবিত উপায়removeObservers:self
পিটারশাইন

deallocআইওএস 6 এ পদ্ধতিটি রাখা এখনও ঠিক আছে কি ?
wcochran

2
হ্যাঁ, যতক্ষণ আপনি [সুপার ডেলোক] না কল করেন ততক্ষণ এআরসি প্রকল্পগুলিতে ডেলোক ব্যবহার করা ঠিক আছে (আপনি যদি [সুপার ডেলোক] কল করেন তবে আপনি একটি সংকলক ত্রুটি পাবেন)। এবং হ্যাঁ, আপনি অবশ্যই আপনার রিমুভালবারটিকে ডেলোকের মধ্যে রাখতে পারেন।
ফিল

উত্তর:


112

জেনেরিক উত্তরটি হবে "যত তাড়াতাড়ি আপনার আর বিজ্ঞপ্তিগুলির প্রয়োজন নেই"। এটি অবশ্যই সন্তোষজনক উত্তর নয় answer

আমি সুপারিশ করব, আপনি যে ক্লাসগুলির [notificationCenter removeObserver: self]পদ্ধতিতে একটি কল যুক্ত করেছেন dealloc, যা আপনি পর্যবেক্ষক হিসাবে ব্যবহার করার ইচ্ছা করছেন, কারণ পর্যবেক্ষককে পরিষ্কারভাবে নিবন্ধন করার এটি সর্বশেষ সুযোগ। এটি কেবলমাত্র মৃত অবজেক্টগুলিকে বিজ্ঞপ্তি কেন্দ্রের কারণে ক্র্যাশগুলির হাত থেকে রক্ষা করবে। এটি আপনার কোডটি বিজ্ঞপ্তিগুলি প্রাপ্তির বিরুদ্ধে রক্ষা করতে পারে না, যখন আপনার অবজেক্টগুলি এখনও / এখনও এমন অবস্থায় নেই যেখানে তারা সঠিকভাবে বিজ্ঞপ্তিটি পরিচালনা করতে পারে। এর জন্য ... উপরে দেখুন

সম্পাদনা (যেহেতু উত্তরটি আমার ধারণার চেয়ে বেশি মন্তব্য আঁকবে) আমি এখানে যা বলার চেষ্টা করছি তা হ'ল: বিজ্ঞপ্তি কেন্দ্র থেকে পর্যবেক্ষককে অপসারণ করা কখন ভাল as সে সম্পর্কে সাধারণ পরামর্শ দেওয়া সত্যিই কঠিন, কারণ এটি নির্ভর করে:

  • আপনার ব্যবহারের ক্ষেত্রে (কোন বিজ্ঞপ্তিগুলি পালন করা হয়? তারা কখন পাঠায়?)
  • পর্যবেক্ষকের বাস্তবায়ন (বিজ্ঞপ্তিগুলি গ্রহণের জন্য এটি কখন প্রস্তুত? কখন এটি আর প্রস্তুত নয়?)
  • পর্যবেক্ষকের উদ্দেশ্যপ্রণোদিত জীবনকাল (এটি কি অন্য কোনও বস্তুর সাথে আবদ্ধ হয়, বলুন, দেখুন বা দেখুন নিয়ামক?)
  • ...

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

আপনি সর্বদা সুরক্ষিতভাবে removeObserver:কোনও বস্তুকে একাধিকবার করতে পারেন (এবং প্রদত্ত পর্যবেক্ষকের সাথে প্রথম প্রথম কলটি সমস্তই নোপস হবে)। সুতরাং: এটি deallocনিশ্চিত করার জন্য এটি (আবার) করার বিষয়ে চিন্তা করুন, তবে প্রথম এবং সর্বাগ্রে: উপযুক্ত মুহুর্তে এটি করুন (যা আপনার ব্যবহারের ক্ষেত্রে নির্ধারিত হয়)।


4
এটি আরসি-র সাথে নিরাপদ নয় এবং সম্ভাব্যভাবে ফুটো হওয়ার কারণ হতে পারে। : এই discsussion দেখুন cocoabuilder.com/archive/cocoa/311831-arc-and-dealloc.html
MobileMon

3
@ মোবাইলবোন আপনি যে নিবন্ধটি সংযুক্ত করেছেন তা আমার বক্তব্যকে মনে হচ্ছে। আমি কী মিস করছি?
শির্ক

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

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

@ মোটরমন "উদাহরণস্বরূপ, viewWillDisappear" একটি কংক্রিট পরামর্শ দেওয়ার ক্ষেত্রে সমস্যাটি হ'ল এটি নির্ভর করে যে আপনি কোন ধরণের ইভেন্টের জন্য পর্যবেক্ষক হিসাবে কোন ধরণের অবজেক্টটি নিবন্ধ করেন on এটি (অথবা ) এর জন্য কোনও পর্যবেক্ষককে নিবন্ধভুক্ত করার সঠিক সমাধান হতে পারে তবে এটি ব্যবহারের ক্ষেত্রে নির্ভর করে। viewWillDisappearviewDidUnloadUIViewController
ডার্ক

39

দ্রষ্টব্য: এটি পরীক্ষা করা হয়েছে এবং 100% শতাংশ কাজ করছে

দ্রুতগতি

override func viewWillDisappear(animated: Bool){
    super.viewWillDisappear(animated)

    if self.navigationController!.viewControllers.contains(self) == false  //any other hierarchy compare if it contains self or not
    {
        // the view has been removed from the navigation stack or hierarchy, back is probably the cause
        // this will be slow with a large stack however.

        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

PresentedViewController

override func viewWillDisappear(animated: Bool){
    super.viewWillDisappear(animated)

    if self.isBeingDismissed()  //presented view controller
    {
        // remove observer here
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
}

উদ্দেশ্য গ

ইন iOS 6.0 > version, তার ভাল পর্যবেক্ষক মুছে ফেলার জন্য viewWillDisappearযেমন viewDidUnloadপদ্ধতি অসমর্থিত হয়েছে।

 [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];

ভিউটিটি remove observerযখন থেকে সরানো হয়েছে তখন তার চেয়ে অনেক বার ভাল navigation stack or hierarchy

- (void)viewWillDisappear:(BOOL)animated{
 if (![[self.navigationController viewControllers] containsObject: self]) //any other hierarchy compare if it contains self or not
    {
        // the view has been removed from the navigation stack or hierarchy, back is probably the cause
        // this will be slow with a large stack however.

        [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
    }
}

PresentedViewController

- (void)viewWillDisappear:(BOOL)animated{
    if ([self isBeingDismissed] == YES) ///presented view controller
    {
        // remove observer here
        [[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
    }
}

8
কোনও নিয়ামক বাদে এখনও তার নোটিশটি না দেখলে বিজ্ঞপ্তি জানতে পারে (উদাহরণস্বরূপ, কোনও টেবিলভিউ পুনরায় লোড করা)।
wcochran

2
@Wcochran স্বয়ংক্রিয়ভাবে পুনরায় লোড / রিফ্রেশ করুনviewWillAppear:
রিচার্ড

@ প্রিন্স আপনি কীভাবে উইলডিস্পারকে আরও ভাল ডিলোকের ব্যাখ্যা করতে পারেন? সুতরাং আমরা স্বতে পর্যবেক্ষক যুক্ত করেছি, সুতরাং যখন স্বকে স্মৃতি থেকে বাদ দেওয়া হবে তখন এটি ডেলোককে ডাকবে এবং তারপরে সমস্ত পর্যবেক্ষক মুছে ফেলা হবে, এটি কি কোনও ভাল যুক্তি নয়।
মাতরোসভ আলেকজান্ডার

যে removeObserver:selfকোনও UIViewControllerলাইফসাইকেল ইভেন্টে কল করা আপনার সপ্তাহকে নষ্ট করার প্রায় গ্যারান্টিযুক্ত। আরও পঠন: সাবজেক্টিভ- উদ্দেশ্যমূলক-
c.blogspot.com/2011/04/…

1
ফেলে removeObserverকল viewWillDisappearহিসাবে উল্লিখিত স্পষ্টভাবে যদি নিয়ামক মাধ্যমে উপস্থাপন করা হচ্ছে যেতে সঠিক উপায় pushViewController। যদি আপনি এর deallocপরিবর্তে এগুলি রাখেন তবে deallocকখনই ডাকা হবে না - আমার অভিজ্ঞতায় কমপক্ষে ...
ক্রিস্টোফার কিং

38

আইওএস 9 এর পরে পর্যবেক্ষকদের অপসারণ করার দরকার নেই।

ওএস এক্স 10.11 এবং আইওএস 9.0 এ এনএসএনটিফিকেশন সেন্টার এবং এনএসডিট্রিবিউটেড নোটিকেশন সেন্টার আর নিবন্ধিত পর্যবেক্ষকদের যে বিজ্ঞপ্তিগুলি পাঠিয়ে দেবে তা আর প্রেরণ করবে না।

https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11NotificationCenter


2
হতে পারে তারা পর্যবেক্ষকদের কাছে বার্তা প্রেরণ করবে না, তবে আমি বিশ্বাস করি যে তারা বুঝতে পেরে তারা তাদের কাছে দৃ strong় রেফারেন্স রাখবে। সেক্ষেত্রে সমস্ত পর্যবেক্ষক স্মৃতিতে থাকবে এবং একটি ফাঁস তৈরি করবে। আমি ভুল হলে আমাকে সংশোধন করুন।
ফার

6
লিঙ্কযুক্ত ডকুমেন্টেশন সম্পর্কে বিস্তারিত যায়। টিএল; ডিআর: এটি একটি দুর্বল উল্লেখ।
সেবাস্তিয়ান

তবে অবশ্যই এটি এখনও প্রয়োজনীয় যদি আপনি বিষয়টিকে তাদের চারপাশে রেফারেন্স করে রাখেন এবং কেবল বিজ্ঞপ্তিগুলি শুনতে চান না
TheEye

25

যদি পর্যবেক্ষককে কোনও ভিউ কন্ট্রোলারে যুক্ত করা হয় তবে আমি দৃ strongly়ভাবে এটি যুক্ত করার এবং এটি viewWillAppearসরিয়ে দেওয়ার পরামর্শ দিচ্ছি viewWillDisappear


আমি কৌতূহলী, @ রিকিজি: আপনি কেন viewWillAppearএবং viewWillDisappearভিউকন্ট্রোলারদের জন্য ব্যবহারের পরামর্শ দিচ্ছেন?
আইজাক ওভারেকার

2
@ আইসাক ওভারেকার কয়েকটি কারণ: আপনার সেট আপ কোড (যেমন লোডভিউ এবং ভিউডিডলড) সম্ভাব্যভাবে বিজ্ঞপ্তিগুলি বহিস্কারের কারণ হতে পারে এবং এটির প্রদর্শিত হওয়ার আগে আপনার নিয়ামককে এটি প্রতিফলিত করতে হবে। আপনি যদি এটি এটি করেন তবে কয়েকটি সুবিধা রয়েছে। এই মুহুর্তে আপনি যে নিয়ামকটিকে বিজ্ঞপ্তিগুলির বিষয়ে চিন্তা করেন না তাকে "ছেড়ে" যাওয়ার সিদ্ধান্ত নিয়েছিলেন এবং নিয়ামক যখন পর্দা বন্ধ করে দেওয়া হচ্ছে তখন তারা আপনাকে যুক্তি দেখাতে বাধ্য করবে না special এমন বিশেষ ক্ষেত্রে রয়েছে যখন নিয়ন্ত্রককে বিজ্ঞপ্তিগুলি গ্রহণ করা উচিত যখন এটি হয় অফ-স্ক্রিন আমার ধারণা আপনি এটি করতে পারবেন না। তবে এর মতো ইভেন্টগুলি সম্ভবত আপনার মডেল হওয়া উচিত।
রিকিগ

1
@ ইসাক ওভারেকার এছাড়াও এআরসি-র সাথে বিজ্ঞপ্তিগুলি বাতিল করতে ডেলোক প্রয়োগ করা অদ্ভুত হবে।
রিকিজি

4
আমি যা চেষ্টা করেছি তাদের মধ্যে আইওএস 7-র সাথে ইউআইভিউকন্ট্রোলারদের সাথে কাজ করার সময় পর্যবেক্ষকদের নিবন্ধকরণ / অপসারণ করার এটি সর্বোত্তম উপায়। একমাত্র ক্যাচটি হ'ল, অনেক ক্ষেত্রে আপনি ইউআইএনএভিগেশন কন্ট্রোলার ব্যবহার করার সময় এবং অন্য ইউআইভিউকন্ট্রোলারটিকে স্ট্যাকের দিকে ঠেলে দেওয়ার সময় পর্যবেক্ষককে অপসারণ করতে চান না। সমাধান: আপনি ভিসি উইলডিস্পায়ারে পপ হচ্ছে কিনা তা পরীক্ষা করতে পারেন [স্বতঃবজডিজমসড] calling
lekksi

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

20
-(void) dealloc {
      [[NSNotificationCenter defaultCenter] removeObserver:self];
      [super dealloc];
}

4
আমি এই নির্দেশাবলীর ক্রমটি ঘুরিয়ে দিয়েছি ... selfপরে ব্যবহার করা [super dealloc]আমাকে নার্ভাস করে তোলে ... (যদিও রিসিভারটি আসলে কোনওভাবে পয়েন্টারটিকে অবজ্ঞার সম্ভাবনা নাও রাখে, ভাল, আপনি কখনই জানেন না যে তারা কীভাবে কার্যকর করেছিলেন NSNotificationCenter)
ডার্ক

হুঁ। এটা আমার জন্য কাজ করেছে। আপনি কোন অস্বাভাবিক আচরণ লক্ষ্য করেছেন?
লেগোলাস

1
ডার্ক ঠিক - এটি ভুল। [super dealloc]সর্বদা আপনার পদ্ধতির সর্বশেষ বিবৃতি হওয়া উচিত dealloc। এটি আপনার বস্তু ধ্বংস করে; এটি চলার পরে, আপনার selfআর বৈধতা নেই। / সিসি @ ডির্ক
জেএসসিএস

38
যদি আইওএস 5+ এ [super dealloc]
আরসি

3
@ পিক্সেলফ্রিয়াক আরও শক্তিশালী, এটিআরসি-এর অধীনে [সুপার ডেলোক]
ট্যাপমনকি ২


7

দ্রুতগতিতে ডিনিট ব্যবহার করুন কারণ ডেললোক অনুপলব্ধ:

deinit {
    ...
}

সুইফ্ট ডকুমেন্টেশন:

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

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


5

* সম্পাদনা করুন: এই পরামর্শ আইওএসের জন্য প্রযোজ্য <= 5 (এমনকি সেখানে আপনাকে যুক্ত করা viewWillAppearএবং সরাতে হবে viewWillDisappear- তবে পরামর্শটি যদি কোনও কারণে আপনি পর্যবেক্ষককে যুক্ত করেছেন তবে প্রয়োগ হয় viewDidLoad)

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


2
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম। দয়া করে মার্কডাউন এফএকিউ পরীক্ষা করুন (প্রশ্ন / উত্তর সম্পাদনা বাক্সের পাশে প্রশ্ন-চিহ্ন আইকন)। মার্কডওয়ন ব্যবহার করা আপনার উত্তরের ব্যবহারযোগ্যতা উন্নত করবে।
মার্কো

5

আমার মতে, নিম্নলিখিত কোডটি এআরসি-তে কোনও অর্থবোধ করে না :

- (void)dealloc
{
      [[NSNotificationCenter defaultCenter] removeObserver:self];
      [super dealloc];
}

ইন iOS 6 এর রয়েছে পর্যবেক্ষক সরানোর কোন মানে নেই viewDidUnload, কারণ এটি এখন অবচিত হয়েছে।

সংক্ষেপে বলতে গেলে, আমি সবসময় এটি করে থাকি viewDidDisappear। তবে এটি আপনার প্রয়োজনীয়তার উপরও নির্ভর করে, ঠিক যেমন @ ডির্ক বলেছিলেন said


আইওএস 6 এর চেয়ে অনেক বেশি লোক এখনও iOS এর পুরানো সংস্করণগুলির জন্য কোড লিখছেন .... :-)
lnafziger

এআরসি তে আপনি এই কোডটি ব্যবহার করতে পারেন তবে লাইনটি ছাড়াই [সুপার ডিলোক]; আপনি এখানে আরও দেখতে পারেন: developer.apple.com/library/ios/#releasenotes/ObjectiveC/…
অ্যালেক্স

1
আপনার যদি নিয়মিত এনএসওবজেক্ট কোনও বিজ্ঞপ্তির পর্যবেক্ষক হয়ে থাকে তবে কী হবে? আপনি এই ক্ষেত্রে dealloc ব্যবহার করবেন?
কিউস

4

আমি মনে করি আমি একটি নির্ভরযোগ্য উত্তর খুঁজে পেয়েছি ! উপরের উত্তরগুলি দ্বিধাহীন বলে মনে হচ্ছে এবং এটি বিরোধী বলে মনে হচ্ছে। আমি কুকবুকস এবং প্রোগ্রামিং গাইডের মাধ্যমে নজর রেখেছি।

প্রথমত, শৈলী addObserver:মধ্যে viewWillAppear:এবং removeObserver:মধ্যে viewWillDisappear:আমার জন্য কাজ (আমি এটা পরীক্ষিত), কারণ আমি পিতা বা মাতা দৃশ্য নিয়ামক কোড চালানো একটি শিশু দৃশ্য নিয়ামক একটি বিজ্ঞপ্তি পোস্ট করছি না। আমি কেবল তখনই এই স্টাইলটি ব্যবহার করব যদি আমি একই ভিউ নিয়ামকের মধ্যে বিজ্ঞপ্তি পোস্ট করে এবং শুনছিলাম।

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

বিএনআর উদাহরণ এক: addObserver:ইন init:, removeObserver:ইনdealloc:

বিএনআর উদাহরণ দুটি: addObserver:ইন awakeFromNib:, removeObserver:ইনdealloc:

… পর্যবেক্ষকগুলিকে সরানোর সময় dealloc:তারা ব্যবহার করবেন না[super dealloc];

আমি আশা করি এটি পরবর্তী ব্যক্তিকে সহায়তা করবে ...

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


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

2

গৃহীত উত্তর নিরাপদ নয় এবং মেমরি ফাঁস হতে পারে। দয়া করে নিবন্ধনটি ডেললোক এ ছেড়ে দিন তবে ভিউইলডিস্পিয়ারে নিবন্ধন করুন (এটি অবশ্যই আপনি ভিউইল অ্যাপয়ারে নিবন্ধন করেন যদি অবশ্যই ....) আমি যা কিছু করি নি এবং এটি দুর্দান্ত কাজ করে! :)


1
আমি এই উত্তরের সাথে একমত আমি ভিউলিডিস্পিয়ারে পর্যবেক্ষকদের অপসারণ না করলে অ্যাপ্লিকেশনটির নিবিড় ব্যবহারের পরে মেমরি সতর্কতা এবং লিকগুলি ক্র্যাশের দিকে পরিচালিত করে experience
সরপার্ডাগ

2

viewWillDisappearভিউ কন্ট্রোলার যখন কোনও নতুন ইউআইভিউ উপস্থাপন করেন তখন এটিকেও লক্ষ্য করা গুরুত্বপূর্ণ । এই প্রতিনিধিটি সহজভাবে নির্দেশ করে যে প্রদর্শনটিতে নিয়ামকটির প্রধান দৃশ্য দৃশ্যমান নয়।

এই ক্ষেত্রে, বিজ্ঞপ্তিটি viewWillDisappearডিলেক্ট করা অসুবিধা হতে পারে যদি আমরা ইউআইভিউকে প্যারেন্ট ভিউ কন্ট্রোলারের সাথে যোগাযোগের অনুমতি দেওয়ার জন্য ব্যবহার করি।

সমাধান হিসাবে আমি সাধারণত এই দুটি পদ্ধতির একটিতে পর্যবেক্ষককে অপসারণ করি:

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"viewController will disappear");
    if ([self isBeingDismissed]) {
        NSLog(@"viewController is being dismissed");
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
    }
}

-(void)dealloc {
    NSLog(@"viewController is being deallocated");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
}

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

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"viewController will appear");
    // Add observers
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"imageGenerated" object:nil]; // This is added to avoid duplicate notifications when the view is presented again
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedImageFromCameraOrPhotolibraryMethodOnListener:) name:@"actionCompleted" object:nil];

}

-1

সুইফট 3

বিজ্ঞপ্তিগুলি ব্যবহারের দুটি ক্ষেত্রে রয়েছে: - ভিউ কন্ট্রোলার স্ক্রিনে থাকা অবস্থায় কেবল সেগুলি প্রয়োজন; - ব্যবহারকারীর বর্তমানের চেয়ে আরও একটি স্ক্রিন খোলার পরেও এগুলি সর্বদা প্রয়োজন।

প্রথম ক্ষেত্রে পর্যবেক্ষক সংযোজন এবং অপসারণের সঠিক জায়গা হ'ল:

/// Add observers
///
/// - Parameter animated: the animation flag
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(...)
}

/// Remove observers
///
/// - Parameter animated: the animation flag
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

দ্বিতীয় ক্ষেত্রে সঠিক উপায়টি হ'ল:

/// Add observers
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(...)
}

/// Remove observers
///
/// - Parameter animated: the animation flag
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if self.isBeingDismissed // remove only when view controller is removed disappear forever
    || !(self.navigationController?.viewControllers.contains(self) ?? true) {
        NotificationCenter.default.removeObserver(self)
    }
}

এবং কখনও প্রবেশ করান removeObserverনা deinit{ ... }- এটি একটি ভুল!


-1
override func viewDidLoad() {   //add observer
  super.viewDidLoad()
  NotificationCenter.default.addObserver(self, selector:#selector(Yourclassname.method), name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}

override func viewWillDisappear(_ animated: Bool) {    //remove observer
    super.viewWillDisappear(true)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.