ব্লক সহ `স্ব`` on cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle cycle।।।।


167

আমি ভয় পাচ্ছি যে এই প্রশ্নটি বেশ বেসিক, তবে আমি মনে করি এটি ব্লকগুলির মধ্যে চলে আসা প্রচুর উদ্দেশ্য-সি প্রোগ্রামারগুলির সাথে প্রাসঙ্গিক।

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

__block typeof(self) bself = self;
[someObject messageWithBlock:^{ [bself doSomething]; }];

পরিবর্তে ন্যায়বিচার

[someObject messageWithBlock:^{ [self doSomething]; }];

আমি যা জানতে চাই তা নীচে: যদি এটি সত্য হয় তবে কি কোনও উপায় আছে যে আমি কদর্যতা এড়াতে পারি (জিসি ব্যবহার বাদ দিয়ে)?


3
আমি আমার selfপ্রক্সিগুলিকে thisকেবল চারপাশের জিনিসগুলি ফ্লিপ করতে কল করতে চাই । জাভাস্ক্রিপ্টে আমি আমার thisক্লোজারগুলিকে কল করি selfতাই এটি সুন্দর এবং ভারসাম্য বোধ করে। :)
ডিভাইস 1

আমি অবাক হয়েছি যে আমি যদি সুইফট ব্লক ব্যবহার করছি তবে কোনও সমমানের ব্যবস্থা নেওয়া দরকার
বেন লু

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

1
সমস্যাগুলি এড়ানোর জন্য, কোনও ব্লকে 'স্ব' ব্যবহারের জন্য যথাযথ উপায়টি হ'ল '__typeof (স্ব) __Wak দুর্বল সেলফ = স্ব;' একটি দুর্বল রেফারেন্স আছে।
XLE_22

উত্তর:


169

কড়া কথায় বলতে গেলে, এটি একটি কনস্টেন্ট অনুলিপিটির এই সমস্যার সাথে কোনও সম্পর্ক নেই। ব্লকগুলি যখন তৈরি করা হয় তখন ক্যাপচার হওয়া কোনও অবজেক্ট-সি মান ধরে রাখতে পারে। এটি ঠিক তাই ঘটে যে কনস্টিপি-অনুলিপি ইস্যুটির জন্য কাজটি ধরে রাখা ইস্যুটির জন্য একইরকম; যথা, __blockভেরিয়েবলের জন্য স্টোরেজ ক্লাস ব্যবহার করে।

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

দয়া করে নোট করুন যে একটি আইভারের রেফারেন্সিংয়ের ঠিক একই সমস্যা রয়েছে। আপনার যদি আপনার ব্লকে একটি আইভার রেফারেন্সের প্রয়োজন হয়, হয় পরিবর্তে কোনও সম্পত্তি ব্যবহার করুন বা ব্যবহার করুন bself->ivar


সংযোজন: আরসি হিসাবে সংকলন করার সময়, __blockআর ধরে রাখার চক্র বিরতি দেয় না। আপনি যদি এআরসি-র জন্য সংকলন করেন তবে আপনার ব্যবহার __weakবা __unsafe_unretainedতার পরিবর্তে এটি প্রয়োজন।


সমস্যা নেই! যদি এটি আপনার সন্তুষ্টির প্রশ্নের উত্তর দেয় তবে আপনি যদি আপনার প্রশ্নের সঠিক উত্তর হিসাবে এটি বেছে নিতে পারেন তবে আমি এটির প্রশংসা করব। যদি তা না হয় তবে দয়া করে আমাকে জানতে দিন আমি কীভাবে আপনার প্রশ্নের উত্তর আরও ভালভাবে দিতে পারি।
লিলি বালার্ড

4
কোনও সমস্যা নেই, কেভিন। SO আপনাকে কোনও প্রশ্নের উত্তর তত্ক্ষণাত্ নির্বাচন করতে বিলম্ব করেছে, তাই আমাকে কিছুক্ষণ পরে ফিরে আসতে হবে। চিয়ার্স।
জোনাথন স্টার্লিং

__unsafe_unretained id bself = স্ব;
কালেব

4
@ জে কেলাইহো: অবশ্যই, __weakঠিক আছে। আপনি যদি কোনও সত্যের জন্য জানেন যে অবরুদ্ধটিটি যখন আহ্বান করা হয় তখন অবজেক্টটি সুযোগের বাইরে চলে যেতে পারে না তবে __unsafe_unretainedএটি খুব সামান্য দ্রুত হয় তবে সাধারণভাবে এটি কোনও পার্থক্য করে না। যদি আপনি এটি ব্যবহার করেন __weak, এটি __strongস্থানীয় ভেরিয়েবলের মধ্যে ফেলে দেওয়ার বিষয়টি নিশ্চিত করুন এবং এটির nilসাথে কিছু করার আগে পরীক্ষা না করে দেখুন।
লিলি ব্যালার্ড

2
@প্রণাতা: হ্যাঁ __blockধরে না রাখা এবং প্রকাশ না করা এর পার্শ্ব-প্রতিক্রিয়াটি সম্পূর্ণরূপে এটি সম্পর্কে সঠিকভাবে যুক্ত করতে অক্ষমতার কারণে। এআরসি দিয়ে, সংকলকটি সেই ক্ষমতা অর্জন করেছে এবং তাই __blockএখন ধরে রাখে এবং প্রকাশিত হয়। আপনার যদি এড়ানো দরকার হয় তবে আপনার ব্যবহার করা উচিত __unsafe_unretained, যা কম্পাইলারকে ভেরিয়েবলের মানটি ধরে রাখার বা প্রকাশ না করার নির্দেশ দেয়।
লিলি বালার্ড

66

শুধু ব্যবহার করুন:

__weak id weakSelf = self;

[someObject someMethodWithBlock:^{
    [weakSelf someOtherMethod];
}];

আরও তথ্যের জন্য: ডাব্লুডাব্লুডিসি 2011 - অনুশীলনে ব্লক এবং গ্র্যান্ড সেন্ট্রাল প্রেরণ

https://developer.apple.com/videos/wwdc/2011/?id=308

দ্রষ্টব্য: যদি এটি কাজ না করে তবে আপনি চেষ্টা করতে পারেন

__weak typeof(self)weakSelf = self;

2
এবং আপনি কি কোনও সুযোগেই এটি খুঁজে পেয়েছেন :)?
টাইম

2
আপনি এখানে ভিডিওটি পরীক্ষা করতে পারেন - developer.apple.com/videos/wwdc/2011/…
নানজুন্ডা

আপনি কি "সামান্যঅথমেথোদ" এর ভিতরে নিজেকে উল্লেখ করতে সক্ষম? স্ব-দুর্বলতার প্রতি সে সময় কী রেফারেন্স দেবে নাকি এটিও বজায় রাখার চক্র তৈরি করবে?
ওরেণ

হাই @ ওরে, আপনি যদি "সামান্যঅথমেথোদ" এর ভিতরে স্ব উল্লেখ করতে চেষ্টা করেন তবে আপনি একটি এক্সকোড সতর্কতা পাবেন। আমার পদ্ধতির স্ব স্ব দুর্বল রেফারেন্স তৈরি করে।
3lvis

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

22

এটি সুস্পষ্ট হতে পারে তবে আপনি কেবল কুরুচিপূর্ণ selfওরফে তখনই করতে হবে যখন আপনি জানেন যে আপনি একটি ধরে রাখার চক্র পাবেন। যদি ব্লকটি কেবলমাত্র এক-শট জিনিস তবে আমি মনে করি আপনি সংরক্ষণটিকে নিরাপদে উপেক্ষা করতে পারবেন self। খারাপ কেসটি যখন আপনি কলব্যাক ইন্টারফেস হিসাবে ব্লক থাকে, উদাহরণস্বরূপ। এখানকার মত:

typedef void (^BufferCallback)(FullBuffer* buffer);

@interface AudioProcessor : NSObject {…}
@property(copy) BufferCallback bufferHandler;
@end

@implementation AudioProcessor

- (id) init {
    
    [self setBufferCallback:^(FullBuffer* buffer) {
        [self whatever];
    }];
    
}

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

typedef void (^Callback)(void);

@interface VideoEncoder : NSObject {…}
- (void) encodeVideoAndCall: (Callback) block;
@end

@interface Foo : NSObject {…}
@property(retain) VideoEncoder *encoder;
@end

@implementation Foo
- (void) somewhere {
    [encoder encodeVideoAndCall:^{
        [self doSomething];
    }];
}

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


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

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

আহ, অবশ্যই, একটি টাইপো আমি retainকিছুক্ষণ আগে এই পর্বটি পেরিয়ে গিয়েছিলাম এবং আপনি যা বলছেন তা দ্রুত উপলব্ধি করেছি :) ধন্যবাদ!
zul

আমি নিশ্চিত retainযে ব্লকগুলির জন্য সম্পূর্ণ উপেক্ষা করা হবে (যদি না তারা ইতিমধ্যে স্ট্যাকটি সরিয়ে নিয়ে থাকে copy)।
স্টিভেন ফিশার 4

@ ডেভ ডিলং, না, যেহেতু এটি ক্রপ হবে না যেহেতু @ প্রপার্টি (ধরে রাখা) কেবল কোনও অবজেক্টের রেফারেন্সের জন্য ব্যবহার করা হয়, ব্লক নয় .. এখানে কোনও অনুলিপি ব্যবহার করার দরকার নেই ..
ডেনিজিওএস

20

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

প্রথম কেসটি দেখায় যে যখন কোনও ধরে রাখার চক্রটি ঘটবে কারণ এতে একটি ব্লক রয়েছে যা ব্লকে উল্লেখ করা হয়:

#import <Foundation/Foundation.h>

typedef void (^MyBlock)(void);

@interface ContainsBlock : NSObject 

@property (nonatomic, copy) MyBlock block;

- (void)callblock;

@end 

@implementation ContainsBlock
@synthesize block = _block;

- (id)init {
    if ((self = [super init])) {

        //__block ContainsBlock *blockSelf = self; // to fix use this.
        self.block = ^{
                NSLog(@"object is %@", self); // self retain cycle
            };
    }
    return self;
}

- (void)dealloc {
    self.block = nil;
    NSLog (@"ContainsBlock"); // never called.
    [super dealloc];
} 

- (void)callblock {
    self.block();
} 

@end 

 int main() {
    ContainsBlock *leaks = [[ContainsBlock alloc] init];
    [leaks callblock];
    [leaks release];
}

দ্বিতীয় ক্ষেত্রে আপনার ব্লকসেলফের দরকার নেই কারণ কলিং অবজেক্টটিতে কোনও ব্লক নেই যা যখন আপনি স্ব উল্লেখ করেন তখন এটি ধরে রাখার চক্র সৃষ্টি করে:

#import <Foundation/Foundation.h>

typedef void (^MyBlock)(void);

@interface BlockCallingObject : NSObject 
@property (copy, nonatomic) MyBlock block;
@end

@implementation BlockCallingObject 
@synthesize block = _block;

- (void)dealloc {
    self.block = nil;
    NSLog(@"BlockCallingObject dealloc");
    [super dealloc];
} 

- (void)callblock {
    self.block();
} 
@end

@interface ObjectCallingBlockCallingObject : NSObject 
@end

@implementation ObjectCallingBlockCallingObject 

- (void)doneblock {
    NSLog(@"block call complete");
}

- (void)dealloc {
    NSLog(@"ObjectCallingBlockCallingObject dealloc");
    [super dealloc];
} 

- (id)init {
    if ((self = [super init])) {

        BlockCallingObject *myobj = [[BlockCallingObject alloc] init];
        myobj.block = ^() {
            [self doneblock]; // block in different object than this object, no retain cycle
        };
        [myobj callblock];
        [myobj release];
    }
    return self;
}
@end

int main() {

    ObjectCallingBlockCallingObject *myObj = [[ObjectCallingBlockCallingObject alloc] init];
    [myObj release];

    return 0;
} 

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

9

এও মনে রাখবেন যে আপনার ব্লক যদি অন্য কোনও অবজেক্টকে ধরে রাখে যা ধরে রাখে তখন ধরে রাখা চক্রগুলি ঘটতে পারে self

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

যেহেতু কোনও পরিষ্কার সমাধান নেই, তাই আমি নীচের কাজের ক্ষেত্রগুলি সুপারিশ করব। আপনার সমস্যা সমাধানের জন্য তাদের মধ্যে এক বা একাধিকটি নির্দ্বিধায় বেছে নিন।

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

আপনি যদি কোনও সার্ভার অবজেক্ট লিখতে থাকেন তবে কেবলমাত্র সম্পূর্ণ করার জন্য ব্লক আর্গুমেন্টগুলি নিন। কলব্যাকগুলির জন্য ব্লক আর্গুমেন্টগুলি গ্রহণ করবেন না setEventHandlerBlock:। পরিবর্তে, ক্লাসিক প্রতিনিধি প্যাটার্নে ফিরে যান: একটি আনুষ্ঠানিক প্রোটোকল তৈরি করুন এবং কোনও setEventDelegate:পদ্ধতির বিজ্ঞাপন দিন । প্রতিনিধি ধরে রাখবেন না। এমনকি আপনি যদি কোনও আনুষ্ঠানিক প্রোটোকল তৈরি করতে না চান তবে কোনও নির্বাচককে একটি প্রতিনিধি কলব্যাক হিসাবে গ্রহণ করুন।

এবং শেষ অবধি, এই প্যাটার্নটির অ্যালার্ম বাজানো উচিত:

- (বাতিল) dealloc
    [মাই সার্ভার অবজেক্ট রিলিজক্যালব্যাক ব্লকসফোরজবজেক্ট: স্ব];
    ...
}

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


আপনি __weakযথাযথভাবে ব্যবহার করলে জিসি সহায়তা করে ।
টিসি।

আবর্জনা সংগ্রহের সন্ধান করা অবশ্যই ধরে রাখা চক্রগুলি মোকাবেলা করতে পারে। পুনরুদ্ধার চক্র শুধুমাত্র রেফারেন্স গণনা পরিবেশের জন্য সমস্যা
newacct

ঠিক তেমনি সকলেই জানেন, আবর্জনা সংগ্রহটি ওএস এক্স ভি 10.8 এ অটোমেটিক রেফারেন্স কাউন্টিং (এআরসি) এর পক্ষে অবহিত করা হয়েছিল এবং ওএস এক্সের ভবিষ্যতের সংস্করণে এটি অপসারণের সময় নির্ধারণ করা হয়েছে ( বিকাশকারী / অ্যাপ্লিকেশন / লাইব্রেরি / ম্যাক /# রিলিজ নোটস / অবজেক্টিভি /… )।
রিকার্ডো সানচেজ-সায়েজ

1

__block __unsafe_unretainedকেভিনের পোস্টে প্রস্তাবিত সংশোধকগুলি অন্য কোনও থ্রেডে মৃত্যুদন্ড কার্যকর করার ক্ষেত্রে খারাপ অ্যাক্সেস ব্যতিক্রমের কারণ হতে পারে। টেম্প ভেরিয়েবলের জন্য এটি কেবলমাত্র __ ব্লক সংশোধক ব্যবহার করা ভাল এবং ব্যবহারের পরে এটি শূন্য করতে পারেন।

__block SomeType* this = self;
[someObject messageWithBlock:^{
  [this doSomething]; // here would be BAD_ACCESS in case of __unsafe_unretained with
                      //  multithreading and self was already released
  this = nil;
}];

ভেরিয়েবলটি ব্যবহারের পরে নিলিংয়ের প্রয়োজনীয়তা এড়াতে __ block এর পরিবর্তে __Wak এর পরিবর্তে কেবল ______ ব্যবহার করা কি আসলেই নিরাপদ হবে না? আমার অর্থ, এই সমাধানটি দুর্দান্ত যদি আপনি অন্য ধরণের চক্রটি ভাঙতে চান তবে অবশ্যই "স্ব" এর উপর চক্র ধরে রাখার জন্য কোনও বিশেষ সুবিধা আমি দেখতে পাচ্ছি না।
ale0xB

আপনার প্ল্যাটফর্মের লক্ষ্য যদি আইওএস ৪.x হয় তবে আপনি __Wak ব্যবহার করতে পারবেন না। এছাড়াও কখনও কখনও আপনার প্রয়োজন যে ব্লকের কোডটি বৈধ বস্তুর জন্য কার্যকর করা হয়েছে, শূন্যতার জন্য নয়।
b1gbr0

1

আপনি Libxtobjc লাইব্রেরি ব্যবহার করতে পারেন। এটি বেশ জনপ্রিয়, উদাহরণস্বরূপ এটি রিঅ্যাকটিভ কোকোয়ায় ব্যবহৃত হয়। https://github.com/jspahrsummers/libextobjc

এটি 2 ম্যাক্রোগুলি @ ওয়াকাইফাই এবং @ স্ট্রংগাইফাই সরবরাহ করে, যাতে আপনি তা করতে পারেন:

@weakify(self)
[someObject messageWithBlock:^{
   @strongify(self)
   [self doSomething]; 
}];

এটি সরাসরি শক্তিশালী রেফারেন্সকে বাধা দেয় যাতে আমরা স্ব-বজায় রাখার চক্রে প্রবেশ করি না। এবং এছাড়াও, এটি অর্ধ-উপায়ে শূন্য হতে স্ব প্রতিরোধ করে, কিন্তু এখনও সঠিকভাবে ধরে রাখা গণনা হ্রাস করে। এই লিঙ্কে আরও: http://aceontech.com/objc/ios/2014/01/10/weakify-a-more-elegant-solution-to-weakself.html


1
সরলীকৃত কোডটি দেখানোর আগে এর পিছনে কী জানা ভাল হবে, প্রত্যেকেরই কোডের আসল দুটি লাইনটি জানা উচিত।
অ্যালেক্স সিও

0

এ কেমন?

- (void) foo {
     __weak __block me = self;

     myBlock = ^ {
        [[me someProp] someMessage];
     }
     ...
 }

সংকলকটির সতর্কতা আমি আর পাই না।


-1

অবরুদ্ধ: একটি ধরে রাখার চক্র ঘটবে কারণ এতে একটি ব্লক রয়েছে যা ব্লকে রেফারেন্সযুক্ত; আপনি যদি ব্লক অনুলিপি তৈরি করেন এবং সদস্যের পরিবর্তনশীল ব্যবহার করেন তবে স্ব স্ব বজায় থাকবে।

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