সিএসএফ স্ট্রিংআরফ এবং সিএফএস স্ট্রিংআরএফ-এ এন সি স্ট্রিং এআরসি-তে এনএসএসআরিং?


89

আমি এআরসি NSStringথেকে একটি পাওয়ার সঠিক CFStringRefউপায়টি বোঝার চেষ্টা করছি ? বিপরীত দিক যাচ্ছে জন্য একই CFStringRefথেকে NSStringএআরসি মধ্যে?

মেমরি ফাঁস তৈরি না করে এটি করার সঠিক উপায় কী?


4
CFStringRef foo (__bridge CFStringRef)theNSString;এবংNSString *bar = (__bridge NSString *)theCFString;

আপনি যখন ব্যাখ্যা করতে পারেন যে এই দুটি বিকল্প ব্যবহার করা হচ্ছে তখন বিশদে কী ঘটছে?
জুমজুম

বেশ না। আমি আরসি ব্যবহার করি না, তাই আমি কেবল জানি যে আপনাকে এটি করতে হবে তবে কেন

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

4
@ H2CO3 উত্তরের জন্য আপনাকে ধন্যবাদ। বিশেষ করে শেষ বাক্যটির সাথে আমি দৃ strongly়ভাবে একমত নই, তবে আমি আপনার দৃষ্টিভঙ্গির প্রতি শ্রদ্ধা জানাচ্ছি :)
গ্যাব্রিয়েল পেট্রোনেলা

উত্তর:


180

সাধারণত

NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

এবং

CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

এখন, আপনি __bridgeকীওয়ার্ডটি কেন রয়েছে তা জানতে চাইলে আপনি অ্যাপল ডকুমেন্টেশনটি উল্লেখ করতে পারেন । সেখানে আপনি পাবেন:

__bridge মালিকানা হস্তান্তর না করে অবজেক্টিভ-সি এবং কোর ফাউন্ডেশনের মধ্যে একটি পয়েন্টার স্থানান্তর করে।

__bridge_retainedবা CFBridgingRetainএকটি মূল ফাউন্ডেশন পয়েন্টারে একটি উদ্দেশ্য-সি পয়েন্টার কাস্ট করে এবং মালিকানাও আপনাকে স্থানান্তর করে। আপনি সিএফআলিজিকে কল করার জন্য বা কোনও সম্পর্কিত ফাংশনটির অবজেক্টটির মালিকানা ত্যাগ করার জন্য দায়বদ্ধ।

__bridge_transferঅথবা CFBridgingReleaseঅবজেক্টিভ সি-তে একটি অ-অবজেক্টিভ-সি পয়েন্টার স্থানান্তরিত করে এবং মালিকানাটি এআরসি-তে স্থানান্তর করে। এআরসি অবজেক্টের মালিকানা ত্যাগের জন্য দায়বদ্ধ।

যার অর্থ হ'ল উপরের ক্ষেত্রে আপনি মালিকানা পরিবর্তন না করে অবজেক্টটিকে কাস্ট করছেন। এটি সূচিত করে যে উভয় ক্ষেত্রেই আপনি স্ট্রিংগুলির মেমরি পরিচালনা করার দায়িত্বে থাকবেন না।

এমন কোনও ক্ষেত্রেও থাকতে পারে যাতে আপনি কোনও কারণে মালিকানা হস্তান্তর করতে চান।

উদাহরণস্বরূপ নিম্নলিখিত স্নিপেট বিবেচনা করুন

- (void)sayHi {
    CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);

    NSString * aNSString = (__bridge NSString *)str;

    NSLog(@"%@", aNSString);

    CFRelease(str); //you have to release the string because you created it with a 'Create' CF function
}

এমন ক্ষেত্রে আপনি CFReleaseকাস্টিংয়ের সময় মালিকানা স্থানান্তর করে একটি সংরক্ষণ করতে চাইতে পারেন ।

- (void)sayHi {
    CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);

    NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
    NSString * aNSString = (NSString *)CFBridgingRelease(str);

    NSLog(@"%@", aNSString);
}

মালিকানা str স্থানান্তরিত হয়েছে, সুতরাং এখন এআরসি আপনার জন্য স্মৃতি মেশানো এবং প্রকাশ করবে।

অন্যান্য উপায় কাছাকাছি আপনি একটি কাস্ট করতে পারেন উপর NSString *একটি থেকে CFStringএকটি ব্যবহার __bridge_retainedকরে কি এমন বস্তু মালিক হবে এবং আপনি স্পষ্টভাবে ব্যবহার করে এটি মুক্তি হবে, ঢালাই, যাতে CFRelease


এটি মোড়ানোর জন্য আপনি থাকতে পারেন

এনএসএসস্ট্রিং → সিএফএস স্ট্রিং

// Don't transfer ownership. You won't have to call `CFRelease`
CFStringRef str = (__bridge CFStringRef)string;

// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you're done with it
CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`

সিএফএসস্ট্রিং → এনএসএসস্ট্রিং

// Don't transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString *string = (__bridge NSString *)str;

// Transfer ownership to ARC. ARC kicks in and it's now in charge of releasing the string object. You won't have to explicitly call `CFRelease` on `str`
NSString *string = (__bridge_transfer NSString *)str;

আপনাকে অনেক ধন্যবাদ, এটি আসলে স্বজ্ঞাত নয়, তবে আপনাকে ধন্যবাদ, পাঠটি শিখেছে
সালফকাইন

@: সামান্য প্রশ্ন। সুতরাং আমরা যদি এআরসি ব্যবহার করি। কখন NSString->CFString, আমাদের ব্যবহার করা উচিত __bridge। কিন্তু কখন CFString->NSString, আমাদের ব্যবহার করা উচিত __bride_transfer। ? এবং কোনও পার্শ্ব-প্রতিক্রিয়া, CFReleaseযখন আমাদের খুব প্রয়োজন হয় না তখন আমরা ব্যবহার করি। ধন্যবাদ :)
hqt

@ htt, আপনি যদি 'সহজ' উপায় চান তবে হ্যাঁ আপনি যা বলছেন তা সঠিক। এছাড়াও, একটি অতিরিক্ত CFReleaseযুক্তিসঙ্গতভাবে আপনার প্রোগ্রামটি ক্র্যাশ করা উচিত, যেহেতু আপনি শেষ পর্যন্ত কোনও NULLপয়েন্টার প্রকাশ না করে মেশানো রেকর্ড / রিলিজ অপারেশনটি শেষ করবেন ।
গ্যাব্রিয়েল পেট্রোনেলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.