سؤال

أحاول إنشاء طريقة تتحقق من وجود سلسلة خالية/لا شيء/فارغة، وأحاول أن أجعلها تعمل كفئة ولكن لم يحالفني الحظ.

أنا أستخدم هذا الرمز بناءً على الإجابات الموجودة في هذا الموضوع:

@implementation NSString (NSStringExtension)
- (BOOL)isNullOrEmpty {
    return self == nil || 
    self == (id)[NSNull null] ||
    [@"" isEqualToString:self] || 
    [[self stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
    [self isEqualToString:@"(null)"]
     || ([self respondsToSelector:@selector(length)] && [(NSData *) self length] == 0)
     || ([self respondsToSelector:@selector(count)] && [(NSArray *) self count] == 0)
     || [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
@end

ولكن عندما أحاول استخدام هذا، هذا ما أحصل عليه:

NSLog([@"" isNullOrEmpty] ? @"1":@"0"); // prints 1
NSString *s1 = nil;
NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([args.itemName isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0

هذا يحيرني، ولا أستطيع إلا أن أفترض أن بعض التركيبات من iOS5/ARC تتسبب في إجبار الكائن nil على سلسلة/مؤشر فارغ.يُظهر مصحح الأخطاء السلسلة كـ 0x0، ولكن عندما أستخدم ملف my isNullOrEmpty الطريقة، أحصل على كاذبة.

هل كانت مفيدة؟

المحلول

return self == nil

هذا لا يمكن أن يحدث أبدا.إذا حاولت إرسال isNullOrEmpty (أو أي رسالة أخرى) إلى nil, لا يحدث شيء (objc_msgSend(), ، الوظيفة المسؤولة عن إرسال الرسائل، تتحقق من وجود أ nil المتلقي كواحد من أول الأشياء التي يفعلها ويجهض).

self == (id)[NSNull null]

وهذا أيضاً لن يحدث أبداً.إذا قمت بإرسال isNullOrEmpty إلى كائن هذا مثيل NSNull, ، طريقتك هنا، وهي طريقة NSString, ، لن يتم استدعاؤه.بدلاً من، NSNullسيكون إصدار (والذي ربما غير موجود).

على نفس المنوال، ([self respondsToSelector:@selector(count)] && [(NSArray *) self count]) لن يحدث أبدا.إذا كان الكائن يكون ان NSArray, ، ثم isNullOrEmpty لن يتم تشغيله أبدًا، لأنه مرة أخرى، إنها طريقة NSString.

في المقابل، [(NSData *) self length] لا يفعل ما تعتقد أنه يفعله. NSString الحالات يفعل الرد على length, ، ولكن صب الكائن ل NSData لا يستخدم NSData إصدار الطريقة - لا يزال ينتهي به الأمر كـ NSString نسخة من length, ، لأن الكائن في الواقع ان NSString (يتم الإرسال فقط في وقت الترجمة؛لا يمكن تغيير أي شيء في وقت التشغيل).

[self isEqualToString:@"(null)"]

هنا يبدو أنك تقوم بالتحقق من ذلك nil مرة أخرى، ولكن يتم تضليلك من قبل التمثيل الذي - التي NSLog يختار متى يطبع nil:

NSLog(@"%@", nil);

يعرض هذا (null) في وحدة التحكم، ولكن هذا لا يعني أن الكائن نفسه عبارة عن سلسلة تحتوي على تلك الأحرف. NSLog فقط يختار تلك السلسلة لعرضها nil.*

العديد من الأشياء التي تقوم بها تتطلب أن يكون هذا في فئة NSObject, ، بحيث الطريقة كان في الواقع يتم استدعاؤه حتى لو لم يكن الكائن NSString.

للتحقق من وجود سلسلة تتكون من مسافة بيضاء فقط، كل ما تحتاجه هو المقارنة بالسلسلة الفارغة @"" بعد قطع المسافة البيضاء:

NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);

* بل والأفضل أن تفعل NSLog(@"%@", [NSNull null]); يعرض <null> (أقواس زاوية بدلاً من الأقواس)، مما يربك بشكل رائع في المرات القليلة الأولى التي تواجهها NSNull.

نصائح أخرى

قد يكون نهج آخر هو تحديد ماكرو بسيط.

giveacodicetagpre.

هو بسيط وفعال.إذا كنت لا تحب وحدات الماكرو، فيمكنك دائما تحويلها إلى مكالمة دالة دون التأثير على بقية الرمز الخاص بك.

- تحديث:

bryan أثار نقطة جيدة.وظيفة مضمنة هي وسيلة رائعة للذهاب.فيما يلي ماكرو محدث سيقيم Str مرة واحدة فقط.

giveacodicetagpre.

في Objective-C، إرسال رسالة إلى nil سيؤدي دائمًا إلى إرجاع 0 (أو NO, ، بنية صفرية، NULL، وما إلى ذلك، اعتمادًا على نوع الإرجاع المعلن).ال isNullOrEmpty لن يتم استدعاء الطريقة التي كتبتها فعليًا عند الإرسال isNullOrEmpty ل nil.انظر الإجابة المقبولة على أرسل رسالة إلى صفر؟ للمزيد من المعلومات.

ربما يمكنك تغيير طريقتك لتكون كذلك isNotNullOrEmpty.ثم قيمة الإرجاع 0 عند الإرسال isNotNullOrEmpty ل nil سوف يكون له معنى.

أنت لا تتصل بطريقتك، ولكن إرسال رسالة إلى لا شيء.

وهذا هو السلوك المتوقع.أنت ترسل رسالة إلى nil بعد كل ذلك.لذا فهي تُرجع إما لا شيء (أو قيمة 0 أخرى).ما هي الدوائر القصيرة التي يجب تحويلها إلى خطأ بحيث تتم طباعة "0" في الحالات الموضحة أدناه:

NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0

يمكنك أيضًا التأكد من عدم استدعاء رسالتك لهذه الحالات عن طريق تعيين نقطة توقف في طريقة الفئة الجديدة.

كما قال الآخرون، الدعوة [nil isNullOrEmpty]; لن يتم تشغيل طريقتك فعليًا.ال nil الكائن هو مجرد ذلك:فارغة نفسها.

كحل، أود أن أقول إنه ليس لأنك تستخدم لغة كائنية التوجه، فلا يجب عليك أبدًا استخدام الوظائف.

BOOL IsStringNilOrEmpty(NSString*)str
{
    return str == nil ||
        str == null ||
        [@"" isEqualToString:str] ||
        [[str stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
        [str isEqualToString:@"(null)"]
        || ([str respondsToSelector:@selector(length)] && [(NSData *) str length] == 0)
        || ([str respondsToSelector:@selector(count)] && [(NSArray *) str count] == 0)
        || [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;   
}

في الواقع، لقد قمت فقط بإصلاح هذه المشكلة عن طريق تشغيله مثل

giveacodicetagpre.

لذلك بدلا من isnullorwhitespace إنها isnotnullorwhitespace.

ها هي طريقتي للتحقق NULL / فارغة

- (nsstring *) nullinputinitwithstring: (nsstring *) Inputstring {

giveacodicetagpre.

}

هل فكرت في إنشاء طريقة فئة على فئة تمتد nsstring؟

nsstring + nsstringtxtensions.h

giveacodicetagpre.

nsstring + nsstringtxtensions.m

giveacodicetagpre.

ثم تستخدمه مثل هذا:

giveacodicetagpre.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top